diff --git a/studies/202607_CX_Discovery_Workshop/README.md b/studies/202607_CX_Discovery_Workshop/README.md index e1df16b..6557252 100644 --- a/studies/202607_CX_Discovery_Workshop/README.md +++ b/studies/202607_CX_Discovery_Workshop/README.md @@ -30,37 +30,40 @@ prompts, grouped by topic → sub-topic) and the **captured-session appendix** Mercury stage. The 8 topics / 26 sub-topics / ~110-minute agenda are the structured form of the source survey. +## Where the content lives: in the notebook + +The topic bank — every topic, sub-topic, and facilitator prompt — lives in +the **`topic-bank` cell** of +[`notebooks/cx_discovery.ipynb`](notebooks/cx_discovery.ipynb) (the code cell +tagged `topic-bank`, right under the title). **Content is edited there, in +Jupyter — never in a `.py` file.** It is the study's verbatim anchor: wording +tracks the source survey +[`docs/cx_discovery_survey.md`](docs/cx_discovery_survey.md) (the original +`cxxm.md`), and the `key` slugs are stable identities the sidebar widgets, +captured notes, and JSON export all key off — never renumber or rename them +casually. The cell's own comment block carries the full editing rules. + +`discoverylib/` holds **code only**: the `Topic`/`SubTopic` schema, the +status vocabulary, and the session engine — every engine function takes the +bank as its first argument. The ~42 sidebar widgets are built by a runtime +loop over `TOPICS`, so board, checklist, script, gate, and export all pick up +a content edit automatically. The test suite reads the tagged cell straight +out of the notebook (no kernel) and pins the content, so `pytest` guards the +bank exactly as shipped. + ## Layout ``` -discoverylib/ # the engine — all content & logic - topics.py # the topic bank (verbatim anchor from the survey) - session.py # status vocabulary, progress, checklist, export payload +notebooks/cx_discovery.ipynb # THE deliverable — content (topic-bank cell) + presentation +discoverylib/ # the engine — code only, no content + session.py # Topic/SubTopic schema, status vocabulary, progress, export payload staging.py # stage/backstage detection (copied verbatim) -notebooks/cx_discovery.ipynb # the deliverable (generated — see below) -scripts/ - build_notebook.py # regenerates the notebook from cell sources - export_report.py # nbconvert → exports/*.html + *.md -tests/ # engine pins + stage/backstage test +scripts/export_report.py # nbconvert → exports/*.html + *.md +tests/ # content pins (read from the notebook) + engine pins + staging test docs/cx_discovery_survey.md # source survey (the original cxxm.md) exports/ # generated report sources ``` -## The notebook is generated - -The notebook wires ~42 Mercury widgets (a status selector + notes box per -topic, a checkbox per sub-topic), all derived from the topic bank so they can't -drift from `discoverylib`. Rather than hand-maintain that JSON, the notebook is -built from readable cell sources in -[`scripts/build_notebook.py`](scripts/build_notebook.py): - -```bash -python scripts/build_notebook.py # regenerate after editing a cell -``` - -Edit facilitation *content* (topics, sub-topics, prompts, scope, minutes) in -[`discoverylib/topics.py`](discoverylib/topics.py) — not in the notebook. - ## Run ```bash @@ -69,15 +72,23 @@ pip install -e ".[dev]" mercury --working-dir . # serve the stage (share this screen) jupyter lab # analyst / facilitator view -pytest # engine pins + stage/backstage +pytest # content pins + engine pins + stage/backstage jupyter nbconvert --to notebook --execute --inplace notebooks/cx_discovery.ipynb # gate python scripts/export_report.py # exports/*.html + *.md for the LLM handoff ``` ## Extending -New or reshaped discovery content is a `discoverylib/topics.py` edit, a test -pin (`tests/test_topics.py` recounts, `tests/test_session.py` for new logic), -then `python scripts/build_notebook.py`. Add a topic and the sidebar controls, -board, checklist, script, gate, and export all pick it up — because they're all -generated from the bank. +New or reshaped discovery content is an edit to the notebook's `topic-bank` +cell in JupyterLab, then: + +1. Re-run the notebook — the in-notebook **gate** recounts the bank + (topics / sub-topics / prompts / key order / agenda minutes); update its + pins if the change is deliberate. +2. `pytest` — `tests/test_topics.py` pins the same shape from outside the + kernel; re-pin the counts there too. + +Add a topic and the sidebar controls, board, checklist, script, gate, and +export all pick it up — they're all derived from `TOPICS` at runtime. New +*logic* (not content) goes in `discoverylib/session.py` with pins in +`tests/test_session.py`. diff --git a/studies/202607_CX_Discovery_Workshop/discoverylib/__init__.py b/studies/202607_CX_Discovery_Workshop/discoverylib/__init__.py index 40c3fe0..c9ffe51 100644 --- a/studies/202607_CX_Discovery_Workshop/discoverylib/__init__.py +++ b/studies/202607_CX_Discovery_Workshop/discoverylib/__init__.py @@ -10,18 +10,13 @@ carries the facilitator's question script and the captured per-topic notes, which the data-appendix export hands to an LLM to draft the survey write-up or feed a downstream business-case study. -Engine/presentation split (Pattern §2): the topic bank and all status / -progress logic live here; the notebook only arranges and renders them. +Code/content split: this package holds the **schema and logic only** — +:class:`Topic`/:class:`SubTopic`, the status vocabulary, and the session +engine. The content (the topic bank itself) lives in the ``topic-bank`` +cell of ``notebooks/cx_discovery.ipynb``, where it is edited in Jupyter; +every engine function takes the bank as its first argument. """ -from .topics import ( - TOPIC_BY_KEY, - TOPIC_KEYS, - TOPICS, - SubTopic, - Topic, - topic, -) from .session import ( COMPLETE, IN_PROGRESS, @@ -33,6 +28,8 @@ from .session import ( STATUSES, ChecklistItem, Progress, + SubTopic, + Topic, TopicState, active_topic_key, agenda_minutes, @@ -45,11 +42,11 @@ from .session import ( ) from .staging import backstage, on_stage -__version__ = "0.1.0" +__version__ = "0.2.0" __all__ = [ - # topic bank - "TOPICS", "TOPIC_BY_KEY", "TOPIC_KEYS", "Topic", "SubTopic", "topic", + # schema + "Topic", "SubTopic", # status vocabulary "STATUSES", "STATUS_LABEL", "STATUS_GLYPH", "STATUS_COLOR", "NOT_STARTED", "IN_PROGRESS", "COMPLETE", "SKIPPED", "normalize_status", diff --git a/studies/202607_CX_Discovery_Workshop/discoverylib/session.py b/studies/202607_CX_Discovery_Workshop/discoverylib/session.py index 941bbeb..1cb0190 100644 --- a/studies/202607_CX_Discovery_Workshop/discoverylib/session.py +++ b/studies/202607_CX_Discovery_Workshop/discoverylib/session.py @@ -2,9 +2,12 @@ Session engine — the discovery workshop's "math". There are no dollars here; the quantities a facilitator and client watch are -**status** and **progress**. This module owns all of it so the notebook only -arranges outputs (Mercury Notebook Pattern §2, engine/presentation split): +**status** and **progress**. This module owns the schema and all of the +logic, but none of the content: the topic bank itself lives in the +``topic-bank`` cell of ``notebooks/cx_discovery.ipynb`` (content belongs on +the Jupyter surface, where it is edited; ``.py`` files hold code only). +* :class:`Topic` / :class:`SubTopic` — the schema the bank is written in, * the topic-status vocabulary (:data:`STATUSES`) and its display glyphs, * :func:`progress` — the "3 / 8 topics complete" headline and its ratios, * :func:`subtopic_checklist` — the live tick-list for the active topic, @@ -12,7 +15,7 @@ arranges outputs (Mercury Notebook Pattern §2, engine/presentation split): raw widget inputs (per-topic status + free-text notes), * :func:`session_json` — the machine-readable export payload (Pattern §5). -Everything is a pure function of ``(status_by_topic, notes_by_topic, +Everything is a pure function of ``(topics, status_by_topic, notes_by_topic, done_subtopics)`` so the in-notebook gate can pin it and the export can dump it. Unknown / missing keys degrade gracefully to "not started" so a half-filled live session never crashes the render. @@ -20,10 +23,34 @@ half-filled live session never crashes the render. from __future__ import annotations -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import Any -from .topics import TOPICS, TOPIC_BY_KEY, Topic + +# ── Schema — what the notebook's topic-bank cell is written in ─────── +@dataclass(frozen=True) +class SubTopic: + """A discussion thread within a topic; its title shows on stage when the + topic is active, its prompts are the backstage facilitation script.""" + + key: str + title: str + prompts: tuple[str, ...] = () + + +@dataclass(frozen=True) +class Topic: + """A client-facing discovery topic: the unit the progress bar counts.""" + + key: str + title: str + scope: str + minutes: int + subtopics: tuple[SubTopic, ...] = field(default_factory=tuple) + + @property + def prompt_count(self) -> int: + return sum(len(st.prompts) for st in self.subtopics) # ── Status vocabulary ──────────────────────────────────────────────── @@ -94,13 +121,15 @@ class Progress: return f"{self.completed}/{self.total} topics complete" -def progress(status_by_topic: dict[str, str]) -> Progress: +def progress( + topics: tuple[Topic, ...], status_by_topic: dict[str, str] +) -> Progress: """Tally topic statuses into the headline :class:`Progress`.""" counts = {s: 0 for s in STATUSES} - for t in TOPICS: + for t in topics: counts[normalize_status(status_by_topic.get(t.key))] += 1 return Progress( - total=len(TOPICS), + total=len(topics), completed=counts[COMPLETE], skipped=counts[SKIPPED], in_progress=counts[IN_PROGRESS], @@ -108,13 +137,15 @@ def progress(status_by_topic: dict[str, str]) -> Progress: ) -def active_topic_key(status_by_topic: dict[str, str]) -> str | None: +def active_topic_key( + topics: tuple[Topic, ...], status_by_topic: dict[str, str] +) -> str | None: """The topic to spotlight on stage: the first in-progress topic, else the first not-started one, else None (everything resolved).""" - for t in TOPICS: + for t in topics: if normalize_status(status_by_topic.get(t.key)) == IN_PROGRESS: return t.key - for t in TOPICS: + for t in topics: if normalize_status(status_by_topic.get(t.key)) == NOT_STARTED: return t.key return None @@ -146,9 +177,9 @@ def subtopic_id(topic_key: str, subtopic_key: str) -> str: # ── Agenda ─────────────────────────────────────────────────────────── -def agenda_minutes() -> int: +def agenda_minutes(topics: tuple[Topic, ...]) -> int: """Sum of the nominal per-topic minute budgets.""" - return sum(t.minutes for t in TOPICS) + return sum(t.minutes for t in topics) # ── Full session state (render + export) ───────────────────────────── @@ -168,19 +199,22 @@ class TopicState: def build_session( + topics: tuple[Topic, ...], status_by_topic: dict[str, str], notes_by_topic: dict[str, str] | None = None, done_subtopics: set[str] | frozenset[str] | None = None, ) -> dict[str, Any]: """Assemble the complete session state the notebook renders and exports. - Pure function of the three raw inputs; safe against missing keys. + Pure function of the bank and the three raw inputs; safe against + missing keys. """ notes_by_topic = notes_by_topic or {} done_subtopics = frozenset(done_subtopics or ()) + by_key = {t.key: t for t in topics} topic_states: list[TopicState] = [] - for t in TOPICS: + for t in topics: status = normalize_status(status_by_topic.get(t.key)) done = sum( 1 for st in t.subtopics if subtopic_id(t.key, st.key) in done_subtopics @@ -201,14 +235,14 @@ def build_session( ) ) - prog = progress(status_by_topic) - active = active_topic_key(status_by_topic) + prog = progress(topics, status_by_topic) + active = active_topic_key(topics, status_by_topic) return { "topics": topic_states, "progress": prog, "active_topic_key": active, - "active_topic": TOPIC_BY_KEY[active] if active else None, - "agenda_minutes": agenda_minutes(), + "active_topic": by_key[active] if active else None, + "agenda_minutes": agenda_minutes(topics), } diff --git a/studies/202607_CX_Discovery_Workshop/discoverylib/staging.py b/studies/202607_CX_Discovery_Workshop/discoverylib/staging.py index 2ec7bec..5fe72dc 100644 --- a/studies/202607_CX_Discovery_Workshop/discoverylib/staging.py +++ b/studies/202607_CX_Discovery_Workshop/discoverylib/staging.py @@ -16,6 +16,7 @@ must appear for LLM consumption) but never render in the Mercury app. from __future__ import annotations import os +from typing import Any def on_stage() -> bool: @@ -23,7 +24,7 @@ def on_stage() -> bool: return os.getenv("MERCURY_CONFIG_DIR") is not None -def backstage(*args, **kwargs) -> None: +def backstage(*args: object, **kwargs: Any) -> None: """``print`` that renders only backstage (JupyterLab, nbconvert).""" if not on_stage(): print(*args, **kwargs) diff --git a/studies/202607_CX_Discovery_Workshop/discoverylib/topics.py b/studies/202607_CX_Discovery_Workshop/discoverylib/topics.py deleted file mode 100644 index b1a4091..0000000 --- a/studies/202607_CX_Discovery_Workshop/discoverylib/topics.py +++ /dev/null @@ -1,428 +0,0 @@ -""" -The discovery topic bank — verbatim source record for the CX Exploration & -Discovery workshop. - -This is the study's ``*_VERBATIM`` anchor (Mercury Notebook Pattern): the -facilitation content, structured but **never paraphrased away from** the -source survey ``docs/cx_discovery_survey.md`` (the original ``cxxm.md``). -Editing the wording of a prompt here is editing the anchor — do it against -the survey, not the notebook. - -Shape ------ -``TOPICS`` is an ordered tuple of :class:`Topic`. Each topic owns an ordered -tuple of :class:`SubTopic`; each sub-topic owns the ordered facilitator -prompts (the questions you actually ask). The stage shows topic titles, the -one-line ``scope`` per topic, and — for the active topic — the sub-topic -titles as a live checklist. The prompts stay **backstage** (your script); -they never render on the client's screen. - -Every topic carries: - -* ``key`` — stable slug (snake_case); the identity used by widgets, notes, - status, and the JSON export. NEVER renumber or rename casually — - captured notes key off it. -* ``title`` — client-facing heading shown on stage. -* ``scope`` — one neutral line shown under the title on stage, so the client - stays oriented without being led by the questions. -* ``minutes`` — nominal facilitation budget, summed into the agenda estimate. - -The content is deliberately data, not prose in the notebook: it is testable, -diffable, and exportable, and the notebook only arranges it. -""" - -from __future__ import annotations - -from dataclasses import dataclass, field - - -@dataclass(frozen=True) -class SubTopic: - """A discussion thread within a topic; its title shows on stage when the - topic is active, its prompts are the backstage facilitation script.""" - - key: str - title: str - prompts: tuple[str, ...] = () - - -@dataclass(frozen=True) -class Topic: - """A client-facing discovery topic: the unit the progress bar counts.""" - - key: str - title: str - scope: str - minutes: int - subtopics: tuple[SubTopic, ...] = field(default_factory=tuple) - - @property - def prompt_count(self) -> int: - return sum(len(st.prompts) for st in self.subtopics) - - -# ── The topic bank ─────────────────────────────────────────────────── -# Ordered as a workshop runs: context first, then the operational areas, -# then the enabling functions, closing on reporting & insight. Wording of -# prompts tracks docs/cx_discovery_survey.md (cxxm.md). - -TOPICS: tuple[Topic, ...] = ( - Topic( - key="background", - title="Background & Organization", - scope="Lines of business, channels, org structure, decision-making", - minutes=15, - subtopics=( - SubTopic( - "lines_of_business", "Lines of business & scope", - ( - "How many distinct lines of business are supported in the " - "contact centre? (e.g. commercial, residential, retail, " - "wholesale)", - "Are you using the contact centre for internal uses such as " - "help desk, finance, HR?", - "Payment card / PCI in scope?", - "What are the availability SLAs or targets for your " - "technology platform?", - ), - ), - SubTopic( - "channels_supported", "Channels supported", - ( - "Which channels do you support today? (Apps, Voice, Video, " - "Chat, SMS, Email, Social Media, Digital Assistants)", - ), - ), - SubTopic( - "org_structure", "Org & reporting structure", - ( - "Mini org chart — reporting structure up to the executive " - "leader.", - "Are your contact centres managed by the same person? " - "(Managers / Team Leads / Agents)", - "Who carries the cost of contact centre agents and " - "supervisors?", - "What revenue is generated by the contact centre?", - ), - ), - SubTopic( - "decision_making", "Decision-making & priorities", - ( - "Is decision-making centralized or decentralized?", - "Who are the key decision makers for changes to the contact " - "centre?", - "How important is CX & EX to your organization's strategy? " - "Is there an executive accountable for CX (CXO, CDO)?", - "Of your leading offers, what is the customer's top priority?", - "Competitive pressures?", - "Any pending or recent acquisitions or spinoffs affecting IT " - "infrastructure and services?", - ), - ), - SubTopic( - "problems_today", "Problems & causes today", - ( - "What do you view as the problems in your contact centre " - "today, and the primary causes?", - "Any in-flight projects — CX or EX improvement initiatives?", - "Are your customer experiences personalized?", - ), - ), - ), - ), - Topic( - key="cx_strategy", - title="CX Strategy", - scope="How CX value is defined, measured, and organized to deliver", - minutes=15, - subtopics=( - SubTopic( - "value_definition", "Value & strategic position", - ( - "How is the value of Customer Experience defined within your " - "organization? Is CX a key BPI, recognized & measured as a " - "financial value?", - "What are the key capabilities / services delivered by the " - "contact centre?", - "How are you using CX innovation to create market " - "disruption?", - "How are competitors using CX to create competitive " - "differentiation?", - ), - ), - SubTopic( - "operating_model", "Organization & operating model", - ( - "Is there a CX team? Do the CX insights team regularly " - "educate the business?", - "Who are the key decision makers for investment and changes " - "to the contact centre? Channel management strategy?", - "What are the teams, and how are processes managed?", - "Describe your automation strategy. Who is your leader for " - "Data & AI?", - ), - ), - SubTopic( - "insight_and_voc", "Insight & Voice of Customer", - ( - "How do you use analytics & data to generate a consolidated " - "view of your customer experience?", - "Is there a VOC program in place? ROI / business value " - "known?", - "How do customers rate the experience they receive (0–5)?", - ), - ), - SubTopic( - "continuous_improvement", "Continuous improvement", - ( - "How is customer insight used to drive CX improvement, " - "loyalty and profitability? How do you anticipate needs?", - "Do you have a clear set of CX design guidelines? (Personas, " - "Journey Mapping, Tools)", - "KPI targets for CX — CSAT, NPS, CES? How are you doing?", - ), - ), - SubTopic( - "employee_engagement", "Employee engagement", - ( - "Describe your employee / agent engagement strategy.", - "How engaged are your people in delivering the customer " - "experience?", - "Do you have a VoA / VoE program in place? How are you " - "doing?", - ), - ), - ), - ), - Topic( - key="channels", - title="Channels", - scope="Inbound & outbound volumes, metrics, contact reasons", - minutes=20, - subtopics=( - SubTopic( - "inbound_context", "Inbound context", - ( - "Hours of operation — any 24×7?", - "Who contacts the contact centre? (Demographics, their " - "situation)", - "Are certain callers or groups prioritized?", - "Languages? (English, Canadian French, Spanish, other)", - ), - ), - SubTopic( - "voice_metrics", "Voice & video metrics", - ( - "Average number of active agents (voice / video).", - "Toll-free numbers & DIDs — approximate quantities.", - "Average Wait Time, Abandon rate, Handle Time, Hold Time, " - "After-call work time.", - "Time to authenticate a caller.", - "% of calls transferred — internally / externally (3rd " - "parties)?", - "Courtesy callback / virtual hold? Post-call survey? First " - "Call Resolution rate? Average revenue per call (sales)?", - ), - ), - SubTopic( - "digital_channels", "Digital channels", - ( - "Email — range of logged-in users, response time, email " - "server.", - "Chat — web (internal/external), app-embedded, SMS, " - "Messenger, WhatsApp, Telegram, iMessage.", - "Website forms, mobile apps.", - ), - ), - SubTopic( - "inbound_reasons", "Inbound contact reasons", - ( - "Top 3–5 inbound contact reasons and approximate % of calls.", - "Cost per call? Average Handle Time?", - "Busiest / least busy days? Seasonal variances?", - "Most difficult, commonly occurring calls? Easiest commonly " - "occurring call?", - ), - ), - SubTopic( - "outbound", "Outbound", - ( - "Hours of operation.", - "Voice (preview / predictive dialer volume), email, SMS, " - "recorded announcement ports.", - "Self-service applications, live agent connect, campaign " - "management, DNC management.", - "Top 3–5 outbound contact reasons and approximate % of " - "calls.", - "After-call work?", - ), - ), - ), - ), - Topic( - key="agent_environment", - title="Agent & Supervisor Environment", - scope="Locations, endpoints, desktop, applications, knowledge", - minutes=10, - subtopics=( - SubTopic( - "locations_endpoints", "Locations & endpoints", - ( - "Location types — WFH / offices.", - "Hard phone, soft phone, CODEC, wireless headset?", - "Agent greeting / pre-recorded messages, whisper " - "announcement.", - "PC — desktop, laptop, VDI.", - ), - ), - SubTopic( - "desktop_apps", "Desktop & applications", - ( - "Agent & supervisor desktop — omnichannel? Custom gadgets, " - "screen pops, workflows.", - "Standard browser? SSO?", - "Applications used to handle calls.", - "Knowledge Management.", - ), - ), - ), - ), - Topic( - key="routing_automation", - title="Routing & Automation", - scope="Self-service, IVR, speech, virtual agents, agent assist, RPA", - minutes=15, - subtopics=( - SubTopic( - "self_service", "Self-service & IVR", - ( - "IVR persona — branding, style guides, voice actors?", - "DTMF and/or speech? Speech recognition, TTS, NLU, voice " - "biometrics.", - "Self-service applications — ID & validate, deflection, " - "situational offer (outage / time of day / scheduled).", - "API integration (CRM). Intent capture, intent prediction, " - "offer push on prediction / account attribute.", - ), - ), - SubTopic( - "virtual_agents", "Virtual agents & assist", - ( - "Virtual agents — which processes?", - "Agent assist?", - "RPA?", - "Current challenges or desired capabilities. Desire to " - "automate. DevOps team?", - ), - ), - SubTopic( - "digital_assistants", "Digital assistant apps", - ( - "Alexa, Google Assistant, Siri?", - ), - ), - ), - ), - Topic( - key="workforce_engagement", - title="Workforce Engagement", - scope="Call recording / QM, WFM, agent self-service, integrations", - minutes=20, - subtopics=( - SubTopic( - "recording_qm", "Call recording & Quality Management", - ( - "How is call recording used? Compliance, screen capture, " - "voice transcription (real-time?), desktop analytics, " - "retention period.", - "Quality team — who do they report to, how many people? " - "Scorecards, score method & metrics, number of assessments, " - "coaching, live monitor.", - "Locations with call recording. Number of named agents.", - ), - ), - SubTopic( - "workforce_management", "Workforce management", - ( - "Recruitment process, required qualifications, average " - "tenure, attrition rate, internal moves.", - "Do you measure agent & supervisor experience? Recognition " - "program?", - "Adherence measure — KPIs, gamification, shift length, " - "breaks, annualized utilization %.", - "Forecasting & scheduling — peak volume, historical data, " - "algorithms, WFM interval (15/30 min).", - "Intraday / real-time adherence — what happens when out of " - "compliance?", - "Payroll integration (ADP / Workday). Satisfaction with " - "current tool(s)? Multiskilled agents, FTE calculations.", - ), - ), - SubTopic( - "agent_self_service", "Agent self-service & integrations", - ( - "Agent self-service — absences, shift bids / swaps, " - "performance metrics.", - "Number of named agents.", - "Integration to 3rd party — outsourcer / overflow, payroll.", - ), - ), - ), - ), - Topic( - key="training", - title="Training", - scope="Onboarding, format, assessment, eLearning, QM integration", - minutes=5, - subtopics=( - SubTopic( - "onboarding", "Onboarding & enablement", - ( - "Onboarding process — how long, training format, " - "assessment?", - "eLearning?", - "QM integration?", - ), - ), - ), - ), - Topic( - key="reporting_insights", - title="Reporting & Insights", - scope="Real-time & historical reporting, analytics, BI, CRM", - minutes=10, - subtopics=( - SubTopic( - "reporting", "Reporting", - ( - "Real-time and historical — what are the key metrics you " - "report on?", - "Data source integration, dashboards, wallboards, agent & " - "supervisor status.", - ), - ), - SubTopic( - "analytics_insights", "Analytics & insights", - ( - "Integrated view of customer details and contact history? " - "CRM?", - "Does the contact centre collect and use customer insight? " - "Predictive engagement?", - "What data analysis do you perform? Analytics / BI team — how " - "many people? BI platform?", - "Executive-level reporting? Marketing team interlock?", - ), - ), - ), - ), -) - - -# ── Lookups ────────────────────────────────────────────────────────── -TOPIC_BY_KEY: dict[str, Topic] = {t.key: t for t in TOPICS} -TOPIC_KEYS: tuple[str, ...] = tuple(t.key for t in TOPICS) - - -def topic(key: str) -> Topic: - """Return the topic with ``key`` (raises ``KeyError`` if unknown).""" - return TOPIC_BY_KEY[key] diff --git a/studies/202607_CX_Discovery_Workshop/notebooks/cx_discovery.ipynb b/studies/202607_CX_Discovery_Workshop/notebooks/cx_discovery.ipynb index b625843..a662b17 100644 --- a/studies/202607_CX_Discovery_Workshop/notebooks/cx_discovery.ipynb +++ b/studies/202607_CX_Discovery_Workshop/notebooks/cx_discovery.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "9cbdb2fa", + "id": "e92e4333", "metadata": {}, "source": [ "# CX Exploration & Discovery Workshop\n", @@ -22,8 +22,9 @@ "LLM-readable report source (notes + status + progress as markdown and JSON)\n", "to feed the survey write-up or a downstream business-case study.\n", "\n", - "All content and logic live in `discoverylib/` — the notebook only arranges\n", - "and renders them.\n", + "The content — every topic, sub-topic, and facilitator prompt — lives in the\n", + "tagged **topic-bank cell** below: edit it here, in the notebook.\n", + "`discoverylib/` holds only the schema and session logic.\n", "\n", "Confidence legend: 🟢 confirmed · 🟡 estimated · 🔴 unknown — used in the\n", "captured notes, not on the client-facing board." @@ -32,24 +33,16 @@ { "cell_type": "code", "execution_count": 1, - "id": "499aa272", + "id": "0e66bf69", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:56.680703Z", - "iopub.status.busy": "2026-07-19T23:20:56.680435Z", - "iopub.status.idle": "2026-07-19T23:20:56.829264Z", - "shell.execute_reply": "2026-07-19T23:20:56.826221Z" + "iopub.execute_input": "2026-07-25T18:27:37.733369Z", + "iopub.status.busy": "2026-07-25T18:27:37.733308Z", + "iopub.status.idle": "2026-07-25T18:27:37.770429Z", + "shell.execute_reply": "2026-07-25T18:27:37.770169Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "discoverylib loaded — 8 topics · 26 sub-topics · 95 prompts\n" - ] - } - ], + "outputs": [], "source": [ "# ── Setup ──────────────────────────────────────────────────────────\n", "import sys, pathlib\n", @@ -62,10 +55,10 @@ "\n", "import mercury as mr\n", "\n", - "# Single source of truth — the topic bank and all status/progress logic\n", - "# live in the library; only presentation (and Mercury widgets) lives here.\n", + "# Schema + session logic come from the library; the CONTENT (the topic\n", + "# bank) lives in the tagged topic-bank cell below — edit it there.\n", "from discoverylib import (\n", - " TOPICS, STATUSES, STATUS_LABEL, STATUS_GLYPH, STATUS_COLOR,\n", + " STATUSES, STATUS_LABEL,\n", " build_session, subtopic_checklist, subtopic_id, session_json,\n", ")\n", "from discoverylib.staging import backstage\n", @@ -79,17 +72,419 @@ "\n", "\n", "def esc(s):\n", - " return _html.escape(str(s))\n", + " return _html.escape(str(s))" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4798dd67", + "metadata": { + "execution": { + "iopub.execute_input": "2026-07-25T18:27:37.771619Z", + "iopub.status.busy": "2026-07-25T18:27:37.771553Z", + "iopub.status.idle": "2026-07-25T18:27:37.778335Z", + "shell.execute_reply": "2026-07-25T18:27:37.778043Z" + }, + "tags": [ + "topic-bank" + ] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "topic bank — 8 topics · 26 sub-topics · 95 prompts\n" + ] + } + ], + "source": [ + "# ── Topic bank — THE study content: edit HERE, in this cell ─────────\n", + "# Verbatim anchor (Mercury Notebook Pattern): the facilitation content,\n", + "# structured but never paraphrased away from the source survey\n", + "# docs/cx_discovery_survey.md (the original cxxm.md). Editing a prompt's\n", + "# wording is editing the anchor — do it against the survey.\n", + "#\n", + "# Rules:\n", + "# * NEVER renumber or rename a `key` — captured notes, sidebar widget\n", + "# state, and the JSON export all key off it.\n", + "# * Editing a topic/sub-topic *title* renames its sidebar widget label,\n", + "# which resets that widget's state mid-session. Prompt wording is\n", + "# backstage-only and safe to edit between sessions.\n", + "# * Keep this cell self-contained (no magics, no other imports): the\n", + "# test suite finds it by its \"topic-bank\" cell tag and execs it to\n", + "# pin the content — after an edit, re-run the notebook (the gate\n", + "# re-checks it) and `pytest` to re-pin.\n", + "#\n", + "# Shape: TOPICS is an ordered tuple of Topic; each topic owns ordered\n", + "# SubTopics; each sub-topic owns the facilitator prompts (the questions\n", + "# you actually ask). The stage shows topic titles, scope lines, and the\n", + "# active topic's sub-topic checklist; prompts stay backstage. `minutes`\n", + "# sums into the agenda estimate. Ordered as a workshop runs: context\n", + "# first, then operational areas, then enabling functions, closing on\n", + "# reporting & insight.\n", + "from discoverylib import SubTopic, Topic, backstage\n", "\n", + "TOPICS: tuple[Topic, ...] = (\n", + " Topic(\n", + " key=\"background\",\n", + " title=\"Background & Organization\",\n", + " scope=\"Lines of business, channels, org structure, decision-making\",\n", + " minutes=15,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"lines_of_business\", \"Lines of business & scope\",\n", + " (\n", + " \"How many distinct lines of business are supported in the \"\n", + " \"contact centre? (e.g. commercial, residential, retail, \"\n", + " \"wholesale)\",\n", + " \"Are you using the contact centre for internal uses such as \"\n", + " \"help desk, finance, HR?\",\n", + " \"Payment card / PCI in scope?\",\n", + " \"What are the availability SLAs or targets for your \"\n", + " \"technology platform?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"channels_supported\", \"Channels supported\",\n", + " (\n", + " \"Which channels do you support today? (Apps, Voice, Video, \"\n", + " \"Chat, SMS, Email, Social Media, Digital Assistants)\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"org_structure\", \"Org & reporting structure\",\n", + " (\n", + " \"Mini org chart — reporting structure up to the executive \"\n", + " \"leader.\",\n", + " \"Are your contact centres managed by the same person? \"\n", + " \"(Managers / Team Leads / Agents)\",\n", + " \"Who carries the cost of contact centre agents and \"\n", + " \"supervisors?\",\n", + " \"What revenue is generated by the contact centre?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"decision_making\", \"Decision-making & priorities\",\n", + " (\n", + " \"Is decision-making centralized or decentralized?\",\n", + " \"Who are the key decision makers for changes to the contact \"\n", + " \"centre?\",\n", + " \"How important is CX & EX to your organization's strategy? \"\n", + " \"Is there an executive accountable for CX (CXO, CDO)?\",\n", + " \"Of your leading offers, what is the customer's top priority?\",\n", + " \"Competitive pressures?\",\n", + " \"Any pending or recent acquisitions or spinoffs affecting IT \"\n", + " \"infrastructure and services?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"problems_today\", \"Problems & causes today\",\n", + " (\n", + " \"What do you view as the problems in your contact centre \"\n", + " \"today, and the primary causes?\",\n", + " \"Any in-flight projects — CX or EX improvement initiatives?\",\n", + " \"Are your customer experiences personalized?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"cx_strategy\",\n", + " title=\"CX Strategy\",\n", + " scope=\"How CX value is defined, measured, and organized to deliver\",\n", + " minutes=15,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"value_definition\", \"Value & strategic position\",\n", + " (\n", + " \"How is the value of Customer Experience defined within your \"\n", + " \"organization? Is CX a key BPI, recognized & measured as a \"\n", + " \"financial value?\",\n", + " \"What are the key capabilities / services delivered by the \"\n", + " \"contact centre?\",\n", + " \"How are you using CX innovation to create market \"\n", + " \"disruption?\",\n", + " \"How are competitors using CX to create competitive \"\n", + " \"differentiation?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"operating_model\", \"Organization & operating model\",\n", + " (\n", + " \"Is there a CX team? Do the CX insights team regularly \"\n", + " \"educate the business?\",\n", + " \"Who are the key decision makers for investment and changes \"\n", + " \"to the contact centre? Channel management strategy?\",\n", + " \"What are the teams, and how are processes managed?\",\n", + " \"Describe your automation strategy. Who is your leader for \"\n", + " \"Data & AI?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"insight_and_voc\", \"Insight & Voice of Customer\",\n", + " (\n", + " \"How do you use analytics & data to generate a consolidated \"\n", + " \"view of your customer experience?\",\n", + " \"Is there a VOC program in place? ROI / business value \"\n", + " \"known?\",\n", + " \"How do customers rate the experience they receive (0–5)?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"continuous_improvement\", \"Continuous improvement\",\n", + " (\n", + " \"How is customer insight used to drive CX improvement, \"\n", + " \"loyalty and profitability? How do you anticipate needs?\",\n", + " \"Do you have a clear set of CX design guidelines? (Personas, \"\n", + " \"Journey Mapping, Tools)\",\n", + " \"KPI targets for CX — CSAT, NPS, CES? How are you doing?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"employee_engagement\", \"Employee engagement\",\n", + " (\n", + " \"Describe your employee / agent engagement strategy.\",\n", + " \"How engaged are your people in delivering the customer \"\n", + " \"experience?\",\n", + " \"Do you have a VoA / VoE program in place? How are you \"\n", + " \"doing?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"channels\",\n", + " title=\"Channels\",\n", + " scope=\"Inbound & outbound volumes, metrics, contact reasons\",\n", + " minutes=20,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"inbound_context\", \"Inbound context\",\n", + " (\n", + " \"Hours of operation — any 24×7?\",\n", + " \"Who contacts the contact centre? (Demographics, their \"\n", + " \"situation)\",\n", + " \"Are certain callers or groups prioritized?\",\n", + " \"Languages? (English, Canadian French, Spanish, other)\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"voice_metrics\", \"Voice & video metrics\",\n", + " (\n", + " \"Average number of active agents (voice / video).\",\n", + " \"Toll-free numbers & DIDs — approximate quantities.\",\n", + " \"Average Wait Time, Abandon rate, Handle Time, Hold Time, \"\n", + " \"After-call work time.\",\n", + " \"Time to authenticate a caller.\",\n", + " \"% of calls transferred — internally / externally (3rd \"\n", + " \"parties)?\",\n", + " \"Courtesy callback / virtual hold? Post-call survey? First \"\n", + " \"Call Resolution rate? Average revenue per call (sales)?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"digital_channels\", \"Digital channels\",\n", + " (\n", + " \"Email — range of logged-in users, response time, email \"\n", + " \"server.\",\n", + " \"Chat — web (internal/external), app-embedded, SMS, \"\n", + " \"Messenger, WhatsApp, Telegram, iMessage.\",\n", + " \"Website forms, mobile apps.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"inbound_reasons\", \"Inbound contact reasons\",\n", + " (\n", + " \"Top 3–5 inbound contact reasons and approximate % of calls.\",\n", + " \"Cost per call? Average Handle Time?\",\n", + " \"Busiest / least busy days? Seasonal variances?\",\n", + " \"Most difficult, commonly occurring calls? Easiest commonly \"\n", + " \"occurring call?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"outbound\", \"Outbound\",\n", + " (\n", + " \"Hours of operation.\",\n", + " \"Voice (preview / predictive dialer volume), email, SMS, \"\n", + " \"recorded announcement ports.\",\n", + " \"Self-service applications, live agent connect, campaign \"\n", + " \"management, DNC management.\",\n", + " \"Top 3–5 outbound contact reasons and approximate % of \"\n", + " \"calls.\",\n", + " \"After-call work?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"agent_environment\",\n", + " title=\"Agent & Supervisor Environment\",\n", + " scope=\"Locations, endpoints, desktop, applications, knowledge\",\n", + " minutes=10,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"locations_endpoints\", \"Locations & endpoints\",\n", + " (\n", + " \"Location types — WFH / offices.\",\n", + " \"Hard phone, soft phone, CODEC, wireless headset?\",\n", + " \"Agent greeting / pre-recorded messages, whisper \"\n", + " \"announcement.\",\n", + " \"PC — desktop, laptop, VDI.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"desktop_apps\", \"Desktop & applications\",\n", + " (\n", + " \"Agent & supervisor desktop — omnichannel? Custom gadgets, \"\n", + " \"screen pops, workflows.\",\n", + " \"Standard browser? SSO?\",\n", + " \"Applications used to handle calls.\",\n", + " \"Knowledge Management.\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"routing_automation\",\n", + " title=\"Routing & Automation\",\n", + " scope=\"Self-service, IVR, speech, virtual agents, agent assist, RPA\",\n", + " minutes=15,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"self_service\", \"Self-service & IVR\",\n", + " (\n", + " \"IVR persona — branding, style guides, voice actors?\",\n", + " \"DTMF and/or speech? Speech recognition, TTS, NLU, voice \"\n", + " \"biometrics.\",\n", + " \"Self-service applications — ID & validate, deflection, \"\n", + " \"situational offer (outage / time of day / scheduled).\",\n", + " \"API integration (CRM). Intent capture, intent prediction, \"\n", + " \"offer push on prediction / account attribute.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"virtual_agents\", \"Virtual agents & assist\",\n", + " (\n", + " \"Virtual agents — which processes?\",\n", + " \"Agent assist?\",\n", + " \"RPA?\",\n", + " \"Current challenges or desired capabilities. Desire to \"\n", + " \"automate. DevOps team?\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"digital_assistants\", \"Digital assistant apps\",\n", + " (\n", + " \"Alexa, Google Assistant, Siri?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"workforce_engagement\",\n", + " title=\"Workforce Engagement\",\n", + " scope=\"Call recording / QM, WFM, agent self-service, integrations\",\n", + " minutes=20,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"recording_qm\", \"Call recording & Quality Management\",\n", + " (\n", + " \"How is call recording used? Compliance, screen capture, \"\n", + " \"voice transcription (real-time?), desktop analytics, \"\n", + " \"retention period.\",\n", + " \"Quality team — who do they report to, how many people? \"\n", + " \"Scorecards, score method & metrics, number of assessments, \"\n", + " \"coaching, live monitor.\",\n", + " \"Locations with call recording. Number of named agents.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"workforce_management\", \"Workforce management\",\n", + " (\n", + " \"Recruitment process, required qualifications, average \"\n", + " \"tenure, attrition rate, internal moves.\",\n", + " \"Do you measure agent & supervisor experience? Recognition \"\n", + " \"program?\",\n", + " \"Adherence measure — KPIs, gamification, shift length, \"\n", + " \"breaks, annualized utilization %.\",\n", + " \"Forecasting & scheduling — peak volume, historical data, \"\n", + " \"algorithms, WFM interval (15/30 min).\",\n", + " \"Intraday / real-time adherence — what happens when out of \"\n", + " \"compliance?\",\n", + " \"Payroll integration (ADP / Workday). Satisfaction with \"\n", + " \"current tool(s)? Multiskilled agents, FTE calculations.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"agent_self_service\", \"Agent self-service & integrations\",\n", + " (\n", + " \"Agent self-service — absences, shift bids / swaps, \"\n", + " \"performance metrics.\",\n", + " \"Number of named agents.\",\n", + " \"Integration to 3rd party — outsourcer / overflow, payroll.\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"training\",\n", + " title=\"Training\",\n", + " scope=\"Onboarding, format, assessment, eLearning, QM integration\",\n", + " minutes=5,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"onboarding\", \"Onboarding & enablement\",\n", + " (\n", + " \"Onboarding process — how long, training format, \"\n", + " \"assessment?\",\n", + " \"eLearning?\",\n", + " \"QM integration?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + " Topic(\n", + " key=\"reporting_insights\",\n", + " title=\"Reporting & Insights\",\n", + " scope=\"Real-time & historical reporting, analytics, BI, CRM\",\n", + " minutes=10,\n", + " subtopics=(\n", + " SubTopic(\n", + " \"reporting\", \"Reporting\",\n", + " (\n", + " \"Real-time and historical — what are the key metrics you \"\n", + " \"report on?\",\n", + " \"Data source integration, dashboards, wallboards, agent & \"\n", + " \"supervisor status.\",\n", + " ),\n", + " ),\n", + " SubTopic(\n", + " \"analytics_insights\", \"Analytics & insights\",\n", + " (\n", + " \"Integrated view of customer details and contact history? \"\n", + " \"CRM?\",\n", + " \"Does the contact centre collect and use customer insight? \"\n", + " \"Predictive engagement?\",\n", + " \"What data analysis do you perform? Analytics / BI team — how \"\n", + " \"many people? BI platform?\",\n", + " \"Executive-level reporting? Marketing team interlock?\",\n", + " ),\n", + " ),\n", + " ),\n", + " ),\n", + ")\n", "\n", - "backstage(f\"discoverylib loaded — {len(TOPICS)} topics · \"\n", + "backstage(f\"topic bank — {len(TOPICS)} topics · \"\n", " f\"{sum(len(t.subtopics) for t in TOPICS)} sub-topics · \"\n", " f\"{sum(t.prompt_count for t in TOPICS)} prompts\")" ] }, { "cell_type": "markdown", - "id": "6f0ea0f6", + "id": "b2bd192b", "metadata": {}, "source": [ "## How to run this session\n", @@ -107,31 +502,31 @@ }, { "cell_type": "code", - "execution_count": 2, - "id": "4ea73b8c", + "execution_count": 3, + "id": "e84c36b2", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:56.833025Z", - "iopub.status.busy": "2026-07-19T23:20:56.832404Z", - "iopub.status.idle": "2026-07-19T23:20:57.008204Z", - "shell.execute_reply": "2026-07-19T23:20:57.006631Z" + "iopub.execute_input": "2026-07-25T18:27:37.779069Z", + "iopub.status.busy": "2026-07-25T18:27:37.779007Z", + "iopub.status.idle": "2026-07-25T18:27:37.811676Z", + "shell.execute_reply": "2026-07-25T18:27:37.811411Z" } }, "outputs": [ { "data": { "application/mercury+json": { - "model_id": "10c8be84f1804c86a5b938888f72c62a", + "model_id": "a451eea831e647c397da7b1450a4a92f", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "10c8be84f1804c86a5b938888f72c62a", + "model_id": "a451eea831e647c397da7b1450a4a92f", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -140,17 +535,17 @@ { "data": { "application/mercury+json": { - "model_id": "e74f98220a094696b7e2525782c140d0", + "model_id": "4577562ceab14ac59502bf3d61b3558b", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "e74f98220a094696b7e2525782c140d0", + "model_id": "4577562ceab14ac59502bf3d61b3558b", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -159,17 +554,17 @@ { "data": { "application/mercury+json": { - "model_id": "5072fb8217314fbe9137e9d55ad9358d", + "model_id": "d04723c27a694c48965d347729954375", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "5072fb8217314fbe9137e9d55ad9358d", + "model_id": "d04723c27a694c48965d347729954375", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -178,17 +573,17 @@ { "data": { "application/mercury+json": { - "model_id": "00b9b1239d634bc69d67508148b4d5df", + "model_id": "96e8b19e7f334299a6b55590bb9161b2", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "00b9b1239d634bc69d67508148b4d5df", + "model_id": "96e8b19e7f334299a6b55590bb9161b2", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -197,17 +592,17 @@ { "data": { "application/mercury+json": { - "model_id": "7d9b61e8dfaf472fabd6a2ce047d6729", + "model_id": "6d51502a805c4ad0a84412e31231a8dc", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "7d9b61e8dfaf472fabd6a2ce047d6729", + "model_id": "6d51502a805c4ad0a84412e31231a8dc", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -216,17 +611,17 @@ { "data": { "application/mercury+json": { - "model_id": "60ee47d42b1d4066877dec2b86577a01", + "model_id": "d1022625168744a897229cff827f8392", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "60ee47d42b1d4066877dec2b86577a01", + "model_id": "d1022625168744a897229cff827f8392", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -235,17 +630,17 @@ { "data": { "application/mercury+json": { - "model_id": "47a1106486e6494e90dfd0616fc7fc0f", + "model_id": "d5d6f1aa4fbd409699530cc1bca9b74d", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "47a1106486e6494e90dfd0616fc7fc0f", + "model_id": "d5d6f1aa4fbd409699530cc1bca9b74d", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -254,17 +649,17 @@ { "data": { "application/mercury+json": { - "model_id": "9adb705fc7cc420da7965276388fafe8", + "model_id": "f31201923cb44e409e1ea78501f97681", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "9adb705fc7cc420da7965276388fafe8", + "model_id": "f31201923cb44e409e1ea78501f97681", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -273,17 +668,17 @@ { "data": { "application/mercury+json": { - "model_id": "b715b892818b46019201b5a688f70dcf", + "model_id": "222761ab30e745dda9d6be0c8e00b184", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "b715b892818b46019201b5a688f70dcf", + "model_id": "222761ab30e745dda9d6be0c8e00b184", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -292,17 +687,17 @@ { "data": { "application/mercury+json": { - "model_id": "20ce1fa7b06e4f86bb137706851bcf84", + "model_id": "3624da047b62467b90bdc02c51190aea", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "20ce1fa7b06e4f86bb137706851bcf84", + "model_id": "3624da047b62467b90bdc02c51190aea", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -311,17 +706,17 @@ { "data": { "application/mercury+json": { - "model_id": "177b5301a0234fdf93277284006e5601", + "model_id": "f669b4e9c5164f8fb734f4f3060e19ea", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "177b5301a0234fdf93277284006e5601", + "model_id": "f669b4e9c5164f8fb734f4f3060e19ea", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -330,17 +725,17 @@ { "data": { "application/mercury+json": { - "model_id": "fe8ea7220e28420aa3f4b8901b51a2d9", + "model_id": "dafa8c55991946a187fe9d550de53414", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "fe8ea7220e28420aa3f4b8901b51a2d9", + "model_id": "dafa8c55991946a187fe9d550de53414", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -349,17 +744,17 @@ { "data": { "application/mercury+json": { - "model_id": "56b21c34e0234fc0b0d83fe950fca3a4", + "model_id": "1b8da4d7656043a789290d8108706dbe", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "56b21c34e0234fc0b0d83fe950fca3a4", + "model_id": "1b8da4d7656043a789290d8108706dbe", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -368,17 +763,17 @@ { "data": { "application/mercury+json": { - "model_id": "1d38c9ccfa4444deb04cf2fb46f91ec0", + "model_id": "70f6f83bca334c7688b05d8a09764cb6", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "1d38c9ccfa4444deb04cf2fb46f91ec0", + "model_id": "70f6f83bca334c7688b05d8a09764cb6", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -387,17 +782,17 @@ { "data": { "application/mercury+json": { - "model_id": "58daff561a724695ba1d32ba3771bd1e", + "model_id": "2defe01408ac4dca857a667365f4a588", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "58daff561a724695ba1d32ba3771bd1e", + "model_id": "2defe01408ac4dca857a667365f4a588", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -406,17 +801,17 @@ { "data": { "application/mercury+json": { - "model_id": "add2dcc4edde499581741451b25b7559", + "model_id": "dfdc4e514e694492a37dcc756e7dc5b7", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "add2dcc4edde499581741451b25b7559", + "model_id": "dfdc4e514e694492a37dcc756e7dc5b7", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -425,17 +820,17 @@ { "data": { "application/mercury+json": { - "model_id": "d9f9a188dd4f48f7a30fcb41e78e8257", + "model_id": "1bfff7ab287c4d8f985e565e10dcf875", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "d9f9a188dd4f48f7a30fcb41e78e8257", + "model_id": "1bfff7ab287c4d8f985e565e10dcf875", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -444,17 +839,17 @@ { "data": { "application/mercury+json": { - "model_id": "7792e81022c344b89b11a308207a6bbe", + "model_id": "77fc6178e65e4d7ca76c8adb00f2c115", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "7792e81022c344b89b11a308207a6bbe", + "model_id": "77fc6178e65e4d7ca76c8adb00f2c115", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -463,17 +858,17 @@ { "data": { "application/mercury+json": { - "model_id": "430f1b8e205b4de7a3c54e8f3db18107", + "model_id": "8193b4d5cb2b4f32853bc9c057f3af1e", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "430f1b8e205b4de7a3c54e8f3db18107", + "model_id": "8193b4d5cb2b4f32853bc9c057f3af1e", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -482,17 +877,17 @@ { "data": { "application/mercury+json": { - "model_id": "9deaa72bbf0948988dfdb57bcf670f40", + "model_id": "03d1b54031a74239931eb8cecd367d12", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "9deaa72bbf0948988dfdb57bcf670f40", + "model_id": "03d1b54031a74239931eb8cecd367d12", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -501,17 +896,17 @@ { "data": { "application/mercury+json": { - "model_id": "f1920f6a825349f1be5e9cd1a22b0708", + "model_id": "b3115751d9fa4beabb2f152ed21a0ae3", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "f1920f6a825349f1be5e9cd1a22b0708", + "model_id": "b3115751d9fa4beabb2f152ed21a0ae3", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -520,17 +915,17 @@ { "data": { "application/mercury+json": { - "model_id": "3f9c462ee81646caaac03ebeb9055ae1", + "model_id": "8368207a3d684c9b955efb9922b8e7b9", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "3f9c462ee81646caaac03ebeb9055ae1", + "model_id": "8368207a3d684c9b955efb9922b8e7b9", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -539,17 +934,17 @@ { "data": { "application/mercury+json": { - "model_id": "15e5250a35484ff0a4b5e5373d0527a0", + "model_id": "fc04710798de44fb99bc55b34300c448", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "15e5250a35484ff0a4b5e5373d0527a0", + "model_id": "fc04710798de44fb99bc55b34300c448", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -558,17 +953,17 @@ { "data": { "application/mercury+json": { - "model_id": "6fa3e0db0dd3463993acc9c18ac10805", + "model_id": "f0d9c25925fc45a8b1005234f675ace8", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "6fa3e0db0dd3463993acc9c18ac10805", + "model_id": "f0d9c25925fc45a8b1005234f675ace8", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -577,17 +972,17 @@ { "data": { "application/mercury+json": { - "model_id": "59e3152d6bde44f4bf75a8d88441b3ec", + "model_id": "35e7d1e45a5d491bad1e9fdb73b239ff", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "59e3152d6bde44f4bf75a8d88441b3ec", + "model_id": "35e7d1e45a5d491bad1e9fdb73b239ff", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -596,17 +991,17 @@ { "data": { "application/mercury+json": { - "model_id": "302c515cbf2f445a8e96a3e557dacfda", + "model_id": "2fa11043750242e997bcb8acebb2b4aa", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "302c515cbf2f445a8e96a3e557dacfda", + "model_id": "2fa11043750242e997bcb8acebb2b4aa", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -615,17 +1010,17 @@ { "data": { "application/mercury+json": { - "model_id": "2f744f3e85324a6c9c56a9c68c37d8af", + "model_id": "a8206b8bd1694936af419af888e57e84", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "2f744f3e85324a6c9c56a9c68c37d8af", + "model_id": "a8206b8bd1694936af419af888e57e84", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -634,17 +1029,17 @@ { "data": { "application/mercury+json": { - "model_id": "15d0aa6ac0714e3685af841c84d13a48", + "model_id": "59d4a779c9eb46a69d092e98bcd5bc3e", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "15d0aa6ac0714e3685af841c84d13a48", + "model_id": "59d4a779c9eb46a69d092e98bcd5bc3e", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -653,17 +1048,17 @@ { "data": { "application/mercury+json": { - "model_id": "0a51d9b2d7ad4cd386911034dd9aecc5", + "model_id": "020ff59743bc4ba384a216439c71fb35", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "0a51d9b2d7ad4cd386911034dd9aecc5", + "model_id": "020ff59743bc4ba384a216439c71fb35", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -672,17 +1067,17 @@ { "data": { "application/mercury+json": { - "model_id": "8755ad066ef049a4beb4ca76d1fc08c6", + "model_id": "b72bd8acfd374276b0ebdd203075c9b6", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "8755ad066ef049a4beb4ca76d1fc08c6", + "model_id": "b72bd8acfd374276b0ebdd203075c9b6", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -691,17 +1086,17 @@ { "data": { "application/mercury+json": { - "model_id": "4e139491242c4e93a13081aca8905d20", + "model_id": "d6fef173bf9e42179464b5034b9728e9", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "4e139491242c4e93a13081aca8905d20", + "model_id": "d6fef173bf9e42179464b5034b9728e9", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -710,17 +1105,17 @@ { "data": { "application/mercury+json": { - "model_id": "902b8644258e4e0394ab71de2de93fe6", + "model_id": "f0fae9e3698e4246ab05f98f02919d30", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "902b8644258e4e0394ab71de2de93fe6", + "model_id": "f0fae9e3698e4246ab05f98f02919d30", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -729,17 +1124,17 @@ { "data": { "application/mercury+json": { - "model_id": "cb06370551d3496ca2e374ed62bf6620", + "model_id": "8686a07e5bd840f181b8fb1295280bc0", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "cb06370551d3496ca2e374ed62bf6620", + "model_id": "8686a07e5bd840f181b8fb1295280bc0", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -748,17 +1143,17 @@ { "data": { "application/mercury+json": { - "model_id": "34862dfebebd43c7a5705d7e63a166d6", + "model_id": "f0aabb7f6d944dfa839728a33422d5c8", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "34862dfebebd43c7a5705d7e63a166d6", + "model_id": "f0aabb7f6d944dfa839728a33422d5c8", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -767,17 +1162,17 @@ { "data": { "application/mercury+json": { - "model_id": "28bce7ca5a814f07a6276251f0521d8a", + "model_id": "ea3fc8677a1c4aec8eca4f0bc1f7a5a8", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "28bce7ca5a814f07a6276251f0521d8a", + "model_id": "ea3fc8677a1c4aec8eca4f0bc1f7a5a8", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -786,17 +1181,17 @@ { "data": { "application/mercury+json": { - "model_id": "d1318d0516724e41b98ac4bc97d5501f", + "model_id": "6c1b7167e9b1427b88bc6294a069c64e", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "d1318d0516724e41b98ac4bc97d5501f", + "model_id": "6c1b7167e9b1427b88bc6294a069c64e", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -805,17 +1200,17 @@ { "data": { "application/mercury+json": { - "model_id": "0e24ed58f9b9415a90fe052a4e3342bf", + "model_id": "ee709981f4454a96b98a9c9bb1e6d4ca", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "0e24ed58f9b9415a90fe052a4e3342bf", + "model_id": "ee709981f4454a96b98a9c9bb1e6d4ca", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -824,17 +1219,17 @@ { "data": { "application/mercury+json": { - "model_id": "6580589f5f7b412f89671530df13090d", + "model_id": "168c33d8a28848079cdc88aa3d753a92", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "6580589f5f7b412f89671530df13090d", + "model_id": "168c33d8a28848079cdc88aa3d753a92", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -843,17 +1238,17 @@ { "data": { "application/mercury+json": { - "model_id": "9831e05d2a98408b9b4072ff81aef0cd", + "model_id": "d980c0367d404f7e9397b9b37021ffbd", "position": "sidebar", "widget": "SelectWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "9831e05d2a98408b9b4072ff81aef0cd", + "model_id": "d980c0367d404f7e9397b9b37021ffbd", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -862,17 +1257,17 @@ { "data": { "application/mercury+json": { - "model_id": "b784c44f81fd4663b94098ffe046af71", + "model_id": "ca66db1b382a49d4af0b4ce9593e6e70", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "b784c44f81fd4663b94098ffe046af71", + "model_id": "ca66db1b382a49d4af0b4ce9593e6e70", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -881,17 +1276,17 @@ { "data": { "application/mercury+json": { - "model_id": "4a36f1141ebc4915af04a7112b8210d3", + "model_id": "37d2712fe6274dfab2b11a0fcdaea8cd", "position": "sidebar", "widget": "CheckboxWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "4a36f1141ebc4915af04a7112b8210d3", + "model_id": "37d2712fe6274dfab2b11a0fcdaea8cd", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -900,17 +1295,17 @@ { "data": { "application/mercury+json": { - "model_id": "4b2fd66370df42679080cb60015fbe3c", + "model_id": "6d8dd95bf76f448ca63954842e0c252d", "position": "sidebar", "widget": "TextInputWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "4b2fd66370df42679080cb60015fbe3c", + "model_id": "6d8dd95bf76f448ca63954842e0c252d", "version_major": 2, "version_minor": 1 }, "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -946,14 +1341,14 @@ }, { "cell_type": "code", - "execution_count": 3, - "id": "aae1a098", + "execution_count": 4, + "id": "24e06a3e", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:57.011339Z", - "iopub.status.busy": "2026-07-19T23:20:57.011038Z", - "iopub.status.idle": "2026-07-19T23:20:57.020306Z", - "shell.execute_reply": "2026-07-19T23:20:57.019001Z" + "iopub.execute_input": "2026-07-25T18:27:37.812296Z", + "iopub.status.busy": "2026-07-25T18:27:37.812238Z", + "iopub.status.idle": "2026-07-25T18:27:37.814419Z", + "shell.execute_reply": "2026-07-25T18:27:37.814214Z" } }, "outputs": [ @@ -977,7 +1372,7 @@ "DONE_SUBTOPICS = {subtopic_id(tk, sk)\n", " for (tk, sk), w in _sub_w.items() if bool(w.value)}\n", "\n", - "SESSION = build_session(STATUS_BY_TOPIC, NOTES_BY_TOPIC, DONE_SUBTOPICS)\n", + "SESSION = build_session(TOPICS, STATUS_BY_TOPIC, NOTES_BY_TOPIC, DONE_SUBTOPICS)\n", "PROGRESS = SESSION[\"progress\"]\n", "\n", "# One curated line on stage; full echo backstage.\n", @@ -988,26 +1383,26 @@ }, { "cell_type": "code", - "execution_count": 4, - "id": "cf857b6f", + "execution_count": 5, + "id": "c6b92da6", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:57.023448Z", - "iopub.status.busy": "2026-07-19T23:20:57.023214Z", - "iopub.status.idle": "2026-07-19T23:20:57.040484Z", - "shell.execute_reply": "2026-07-19T23:20:57.039569Z" + "iopub.execute_input": "2026-07-25T18:27:37.814991Z", + "iopub.status.busy": "2026-07-25T18:27:37.814934Z", + "iopub.status.idle": "2026-07-25T18:27:37.820348Z", + "shell.execute_reply": "2026-07-25T18:27:37.820155Z" } }, "outputs": [ { "data": { "application/mercury+json": { - "model_id": "cf76fb8741fe4e29ae6f8d1202443f99", + "model_id": "40f2f5c8dcf34b8eb272fcb0680dfa00", "position": "inline", "widget": "MarkdownWidget" }, "application/vnd.jupyter.widget-view+json": { - "model_id": "cf76fb8741fe4e29ae6f8d1202443f99", + "model_id": "40f2f5c8dcf34b8eb272fcb0680dfa00", "version_major": 2, "version_minor": 0 }, @@ -1085,7 +1480,7 @@ }, { "cell_type": "markdown", - "id": "0d679c91", + "id": "421e6d11", "metadata": {}, "source": [ "## Facilitator question script (backstage)\n", @@ -1098,14 +1493,14 @@ }, { "cell_type": "code", - "execution_count": 5, - "id": "a7d4ee27", + "execution_count": 6, + "id": "d70653b9", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:57.042882Z", - "iopub.status.busy": "2026-07-19T23:20:57.042600Z", - "iopub.status.idle": "2026-07-19T23:20:57.048911Z", - "shell.execute_reply": "2026-07-19T23:20:57.047582Z" + "iopub.execute_input": "2026-07-25T18:27:37.820966Z", + "iopub.status.busy": "2026-07-25T18:27:37.820910Z", + "iopub.status.idle": "2026-07-25T18:27:37.822712Z", + "shell.execute_reply": "2026-07-25T18:27:37.822507Z" } }, "outputs": [ @@ -1314,7 +1709,7 @@ }, { "cell_type": "markdown", - "id": "b5609e12", + "id": "5fd4bc7f", "metadata": {}, "source": [ "## Verification & assertions\n", @@ -1327,14 +1722,14 @@ }, { "cell_type": "code", - "execution_count": 6, - "id": "0b8e617b", + "execution_count": 7, + "id": "cc5c3a6e", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:57.051159Z", - "iopub.status.busy": "2026-07-19T23:20:57.050927Z", - "iopub.status.idle": "2026-07-19T23:20:57.056852Z", - "shell.execute_reply": "2026-07-19T23:20:57.056059Z" + "iopub.execute_input": "2026-07-25T18:27:37.823280Z", + "iopub.status.busy": "2026-07-25T18:27:37.823225Z", + "iopub.status.idle": "2026-07-25T18:27:37.825928Z", + "shell.execute_reply": "2026-07-25T18:27:37.825722Z" } }, "outputs": [ @@ -1353,9 +1748,15 @@ " assert cond, msg\n", "\n", "\n", - "# Engine shape — independent of widget state (Pattern §4)\n", + "# Content shape — the bank lives in this notebook, so the gate is its\n", + "# closest guard; recount these pins on any deliberate content change.\n", "_assert(len(TOPICS) == 8, \"expected 8 topics\")\n", "_assert(sum(len(t.subtopics) for t in TOPICS) == 26, \"expected 26 sub-topics\")\n", + "_assert(sum(t.prompt_count for t in TOPICS) == 95, \"expected 95 prompts\")\n", + "_assert(tuple(t.key for t in TOPICS) == (\n", + " \"background\", \"cx_strategy\", \"channels\", \"agent_environment\",\n", + " \"routing_automation\", \"workforce_engagement\", \"training\",\n", + " \"reporting_insights\"), \"topic keys / order drifted\")\n", "_assert(SESSION[\"agenda_minutes\"] == 110, \"agenda minutes drifted\")\n", "_assert(set(STATUS_BY_TOPIC) == {t.key for t in TOPICS}, \"status keys ≠ topics\")\n", "\n", @@ -1383,7 +1784,7 @@ }, { "cell_type": "markdown", - "id": "8b2aceb5", + "id": "bb550a85", "metadata": {}, "source": [ "## Data appendix — for the machines\n", @@ -1396,14 +1797,14 @@ }, { "cell_type": "code", - "execution_count": 7, - "id": "c334037c", + "execution_count": 8, + "id": "ea73c809", "metadata": { "execution": { - "iopub.execute_input": "2026-07-19T23:20:57.059694Z", - "iopub.status.busy": "2026-07-19T23:20:57.059500Z", - "iopub.status.idle": "2026-07-19T23:20:57.064010Z", - "shell.execute_reply": "2026-07-19T23:20:57.063460Z" + "iopub.execute_input": "2026-07-25T18:27:37.826553Z", + "iopub.status.busy": "2026-07-25T18:27:37.826496Z", + "iopub.status.idle": "2026-07-25T18:27:37.828603Z", + "shell.execute_reply": "2026-07-25T18:27:37.828394Z" } }, "outputs": [ @@ -1570,7 +1971,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -1589,41 +1990,7 @@ "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { - "00b9b1239d634bc69d67508148b4d5df": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Background & Organization: Org & reporting structure", - "last_changed_at": "", - "layout": "IPY_MODEL_3582587d7a27431c8be9d3ffa024c89a", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "0a51d9b2d7ad4cd386911034dd9aecc5": { + "020ff59743bc4ba384a216439c71fb35": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -1645,7 +2012,7 @@ "hidden": false, "label": "Routing & Automation: Digital assistant apps", "last_changed_at": "", - "layout": "IPY_MODEL_435bc3967cff4beca08ca48f0fbb0e08", + "layout": "IPY_MODEL_85f77e3f4ac341ea8465de7ed8e60362", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -1657,7 +2024,41 @@ "value": false } }, - "0ab5bbef78284ad0a011dcc2145a3850": { + "03d1b54031a74239931eb8cecd367d12": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Channels: Outbound", + "last_changed_at": "", + "layout": "IPY_MODEL_52d9e6ee9d2746e69d60cc3af8f5b01d", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "1491ef06c9ea4b15b3c72de83b38a374": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -1710,286 +2111,7 @@ "width": null } }, - "0e24ed58f9b9415a90fe052a4e3342bf": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Training: Onboarding & enablement", - "last_changed_at": "", - "layout": "IPY_MODEL_e82e2575b84843408f189ddcc5d8ef7b", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "10c8be84f1804c86a5b938888f72c62a": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "Background & Organization — status", - "layout": "IPY_MODEL_99c1f394d8574e71a04e6176d2d84f56", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "12a61c0a73aa4ae2ae27fcd72263c63b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "15d0aa6ac0714e3685af841c84d13a48": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Routing & Automation: Virtual agents & assist", - "last_changed_at": "", - "layout": "IPY_MODEL_fa59fa350540437ab65cddd0b948f6b1", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "15e5250a35484ff0a4b5e5373d0527a0": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Agent & Supervisor Environment: Locations & endpoints", - "last_changed_at": "", - "layout": "IPY_MODEL_3e25e9ac4d99430ea90d49fcff188012", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "15e74d13d1f64de986496744c61d5c83": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "177b5301a0234fdf93277284006e5601": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "CX Strategy: Insight & Voice of Customer", - "last_changed_at": "", - "layout": "IPY_MODEL_3c56541c5ac947d580197bbc3b563f95", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "1d38c9ccfa4444deb04cf2fb46f91ec0": { + "168c33d8a28848079cdc88aa3d753a92": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -2008,8 +2130,8 @@ "cell_id": "", "disabled": false, "hidden": false, - "label": "CX Strategy — notes", - "layout": "IPY_MODEL_43b4cb6836d04c4f8142a30162d0a0b5", + "label": "Training — notes", + "layout": "IPY_MODEL_5ea3a44bff7c4ce4a63937abc5abf078", "layout_path": null, "position": "sidebar", "render_slot_id": null, @@ -2020,41 +2142,7 @@ "value": "" } }, - "20ce1fa7b06e4f86bb137706851bcf84": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "CX Strategy: Organization & operating model", - "last_changed_at": "", - "layout": "IPY_MODEL_2ec3c1ec05134ea684623d1d8ca06539", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "23a8c7e3fe9e4b8787f7fd1fb2064744": { + "194b98c3b1ab4c828036e196974cbbfa": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -2107,1070 +2195,7 @@ "width": null } }, - "2881f086a4d14abab56d6508fcf62218": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "28bce7ca5a814f07a6276251f0521d8a": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.text.TextInputWidget", - "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Workforce Engagement — notes", - "layout": "IPY_MODEL_5be92f6bff24419a8d94e338c04d46b8", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "" - } - }, - "2ec3c1ec05134ea684623d1d8ca06539": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "2f744f3e85324a6c9c56a9c68c37d8af": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Routing & Automation: Self-service & IVR", - "last_changed_at": "", - "layout": "IPY_MODEL_365e451d9846410493eb519208cfb622", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "302c515cbf2f445a8e96a3e557dacfda": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "Routing & Automation — status", - "layout": "IPY_MODEL_b7a69a28f88c4931a808d6d2e326c0f0", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "31b207b364744fa49b3c184e0a418ea9": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "34862dfebebd43c7a5705d7e63a166d6": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Workforce Engagement: Agent self-service & integrations", - "last_changed_at": "", - "layout": "IPY_MODEL_c39e774f768b45d78f9598309178ba62", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "3582587d7a27431c8be9d3ffa024c89a": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "365e451d9846410493eb519208cfb622": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "3c56541c5ac947d580197bbc3b563f95": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "3e25e9ac4d99430ea90d49fcff188012": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "3f9c462ee81646caaac03ebeb9055ae1": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "Agent & Supervisor Environment — status", - "layout": "IPY_MODEL_4d8023b402724e7784ed8ee4b21947bc", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "430f1b8e205b4de7a3c54e8f3db18107": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Channels: Inbound contact reasons", - "last_changed_at": "", - "layout": "IPY_MODEL_23a8c7e3fe9e4b8787f7fd1fb2064744", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "435bc3967cff4beca08ca48f0fbb0e08": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "43b4cb6836d04c4f8142a30162d0a0b5": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "47a1106486e6494e90dfd0616fc7fc0f": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.text.TextInputWidget", - "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Background & Organization — notes", - "layout": "IPY_MODEL_50a99454ae3e4afdbca65b9f3ee89f7f", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "" - } - }, - "4951ecab2a9f4831b6e041a52fbb0884": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "4a36f1141ebc4915af04a7112b8210d3": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Reporting & Insights: Analytics & insights", - "last_changed_at": "", - "layout": "IPY_MODEL_71726fecf063433a9f4238fa2d128baa", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "4b2fd66370df42679080cb60015fbe3c": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.text.TextInputWidget", - "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Reporting & Insights — notes", - "layout": "IPY_MODEL_ed27b6ab00fb439bafd27011900a74b3", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "" - } - }, - "4d8023b402724e7784ed8ee4b21947bc": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "4dff1758d76c42e1a8fab271fe5b12c9": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "4e139491242c4e93a13081aca8905d20": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "Workforce Engagement — status", - "layout": "IPY_MODEL_83561ff5a0204591b878c5a06b005077", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "5072fb8217314fbe9137e9d55ad9358d": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Background & Organization: Channels supported", - "last_changed_at": "", - "layout": "IPY_MODEL_621bea40095a4cef99638ef88d8143f3", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "50a99454ae3e4afdbca65b9f3ee89f7f": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "56b21c34e0234fc0b0d83fe950fca3a4": { + "1b8da4d7656043a789290d8108706dbe": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -3192,7 +2217,7 @@ "hidden": false, "label": "CX Strategy: Employee engagement", "last_changed_at": "", - "layout": "IPY_MODEL_d305544e68144c3ab7b149512b6a568d", + "layout": "IPY_MODEL_6a6c72a002a14996806931189dc2a762", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -3204,7 +2229,128 @@ "value": false } }, - "58daff561a724695ba1d32ba3771bd1e": { + "1bfff7ab287c4d8f985e565e10dcf875": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Channels: Voice & video metrics", + "last_changed_at": "", + "layout": "IPY_MODEL_4bf057077ef54111826b01e09cb0c2d7", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "21e165b51f474b6f857732aa667bb185": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "222761ab30e745dda9d6be0c8e00b184": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "CX Strategy: Value & strategic position", + "last_changed_at": "", + "layout": "IPY_MODEL_39162785d9954803a67e4053ec694ad9", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "2defe01408ac4dca857a667365f4a588": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -3230,7 +2376,7 @@ "disabled": false, "hidden": false, "label": "Channels — status", - "layout": "IPY_MODEL_97e1eeedec7248378d41ed0f9c1b7396", + "layout": "IPY_MODEL_5a26381ab5a546edb671524ffec3093d", "layout_path": null, "position": "sidebar", "render_slot_id": null, @@ -3241,7 +2387,203 @@ "value": "Not started" } }, - "59e3152d6bde44f4bf75a8d88441b3ec": { + "2e29bd2928674e31b3fd1e2d485a29ed": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "2fa11043750242e997bcb8acebb2b4aa": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "Routing & Automation — status", + "layout": "IPY_MODEL_f756ed14bebb4b1787445e09b080dd1d", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "2fbc83509c604715ba49f524282af285": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "31ce043e86034f2c89ab70982964edba": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "35e7d1e45a5d491bad1e9fdb73b239ff": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -3261,7 +2603,7 @@ "disabled": false, "hidden": false, "label": "Agent & Supervisor Environment — notes", - "layout": "IPY_MODEL_75b5b7a4336d4f889cd6ebf217a9d183", + "layout": "IPY_MODEL_21e165b51f474b6f857732aa667bb185", "layout_path": null, "position": "sidebar", "render_slot_id": null, @@ -3272,60 +2614,7 @@ "value": "" } }, - "5be92f6bff24419a8d94e338c04d46b8": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "60ee47d42b1d4066877dec2b86577a01": { + "3624da047b62467b90bdc02c51190aea": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -3345,9 +2634,9 @@ "cell_id": "", "disabled": false, "hidden": false, - "label": "Background & Organization: Problems & causes today", + "label": "CX Strategy: Organization & operating model", "last_changed_at": "", - "layout": "IPY_MODEL_7babb32651334fe68bacf11917a1da77", + "layout": "IPY_MODEL_5b191db98ba842e59c70203d4442805b", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -3359,91 +2648,7 @@ "value": false } }, - "621bea40095a4cef99638ef88d8143f3": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "6580589f5f7b412f89671530df13090d": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.text.TextInputWidget", - "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Training — notes", - "layout": "IPY_MODEL_0ab5bbef78284ad0a011dcc2145a3850", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "" - } - }, - "6fa3e0db0dd3463993acc9c18ac10805": { + "37d2712fe6274dfab2b11a0fcdaea8cd": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -3463,9 +2668,9 @@ "cell_id": "", "disabled": false, "hidden": false, - "label": "Agent & Supervisor Environment: Desktop & applications", + "label": "Reporting & Insights: Analytics & insights", "last_changed_at": "", - "layout": "IPY_MODEL_4dff1758d76c42e1a8fab271fe5b12c9", + "layout": "IPY_MODEL_ad71bc9d32cb4684af8498f125a65bdf", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -3477,7 +2682,7 @@ "value": false } }, - "71726fecf063433a9f4238fa2d128baa": { + "39162785d9954803a67e4053ec694ad9": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -3530,7 +2735,7 @@ "width": null } }, - "75b5b7a4336d4f889cd6ebf217a9d183": { + "40d26c433bd2492a89755d08a1214a27": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -3583,1126 +2788,7 @@ "width": null } }, - "7792e81022c344b89b11a308207a6bbe": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Channels: Digital channels", - "last_changed_at": "", - "layout": "IPY_MODEL_7ad75e658e8747c6a4505f610dc4cc49", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "7ad75e658e8747c6a4505f610dc4cc49": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7babb32651334fe68bacf11917a1da77": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "7d9b61e8dfaf472fabd6a2ce047d6729": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Background & Organization: Decision-making & priorities", - "last_changed_at": "", - "layout": "IPY_MODEL_dfe2dc69f8934f73b60c9f253afb3c08", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "83561ff5a0204591b878c5a06b005077": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "847e0e2f550344a6a78bc59767419338": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8755ad066ef049a4beb4ca76d1fc08c6": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.text.TextInputWidget", - "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Routing & Automation — notes", - "layout": "IPY_MODEL_fa22be1733f348b69c788b81315f5fd1", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "" - } - }, - "8b204e5fca814a74874b84ceef255495": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8e5fb4e5e45542e8a283674969277d5d": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "8eaf41bd51594842a7ac8274d5f5f70b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "900b88896e664a0c8c40a305da44ffb4": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "902b8644258e4e0394ab71de2de93fe6": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Workforce Engagement: Call recording & Quality Management", - "last_changed_at": "", - "layout": "IPY_MODEL_b08c18e82f4947b3a96da2211bd7f433", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "97e1eeedec7248378d41ed0f9c1b7396": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "9831e05d2a98408b9b4072ff81aef0cd": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "Reporting & Insights — status", - "layout": "IPY_MODEL_2881f086a4d14abab56d6508fcf62218", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "99c1f394d8574e71a04e6176d2d84f56": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "9adb705fc7cc420da7965276388fafe8": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.select.SelectWidget", - "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "cell_id": "", - "choices": [ - "Not started", - "In progress", - "Complete", - "Skipped" - ], - "disabled": false, - "hidden": false, - "label": "CX Strategy — status", - "layout": "IPY_MODEL_31b207b364744fa49b3c184e0a418ea9", - "layout_path": null, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": "Not started" - } - }, - "9deaa72bbf0948988dfdb57bcf670f40": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Channels: Outbound", - "last_changed_at": "", - "layout": "IPY_MODEL_12a61c0a73aa4ae2ae27fcd72263c63b", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "add2dcc4edde499581741451b25b7559": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Channels: Inbound context", - "last_changed_at": "", - "layout": "IPY_MODEL_900b88896e664a0c8c40a305da44ffb4", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "b08c18e82f4947b3a96da2211bd7f433": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "b715b892818b46019201b5a688f70dcf": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "CX Strategy: Value & strategic position", - "last_changed_at": "", - "layout": "IPY_MODEL_f970d4839d8f4511ab9e995f0da3e706", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "b784c44f81fd4663b94098ffe046af71": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Reporting & Insights: Reporting", - "last_changed_at": "", - "layout": "IPY_MODEL_15e74d13d1f64de986496744c61d5c83", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "b7a69a28f88c4931a808d6d2e326c0f0": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "c39e774f768b45d78f9598309178ba62": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "cb06370551d3496ca2e374ed62bf6620": { - "model_module": "anywidget", - "model_module_version": "~0.11.*", - "model_name": "AnyModel", - "state": { - "_anywidget_id": "mercury.checkbox.CheckboxWidget", - "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", - "_dom_classes": [], - "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", - "_model_module": "anywidget", - "_model_module_version": "~0.11.*", - "_model_name": "AnyModel", - "_view_count": null, - "_view_module": "anywidget", - "_view_module_version": "~0.11.*", - "_view_name": "AnyView", - "appearance": "box", - "cell_id": "", - "disabled": false, - "hidden": false, - "label": "Workforce Engagement: Workforce management", - "last_changed_at": "", - "layout": "IPY_MODEL_4951ecab2a9f4831b6e041a52fbb0884", - "layout_path": null, - "n_toggles": 0, - "position": "sidebar", - "render_slot_id": null, - "source_cell_id": null, - "tabbable": null, - "tooltip": null, - "url_key": "", - "value": false - } - }, - "cda4056ee6f1451696fbd29c12b8f3f7": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "cf76fb8741fe4e29ae6f8d1202443f99": { + "40f2f5c8dcf34b8eb272fcb0680dfa00": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLModel", @@ -4718,19 +2804,723 @@ "cell_id": "", "description": "", "description_allow_html": false, - "layout": "IPY_MODEL_847e0e2f550344a6a78bc59767419338", + "layout": "IPY_MODEL_b70b532c7b0942f792415fc6c0fe5fa7", "layout_path": null, "placeholder": "​", "position": "inline", "render_slot_id": null, "source_cell_id": null, - "style": "IPY_MODEL_ec1be2c8173343f6b2829c950f4bffc8", + "style": "IPY_MODEL_78e6ef2a955749668cd65184d203e3b9", "tabbable": null, "tooltip": null, "value": "
CX Discovery — topics
8 topics · ~110 minutes
0 of 8 topics complete
Background & Organizationdiscussing now →Not started
Lines of business, channels, org structure, decision-making
  • Lines of business & scope
  • Channels supported
  • Org & reporting structure
  • Decision-making & priorities
  • Problems & causes today
CX StrategyNot started
How CX value is defined, measured, and organized to deliver
ChannelsNot started
Inbound & outbound volumes, metrics, contact reasons
Agent & Supervisor EnvironmentNot started
Locations, endpoints, desktop, applications, knowledge
Routing & AutomationNot started
Self-service, IVR, speech, virtual agents, agent assist, RPA
Workforce EngagementNot started
Call recording / QM, WFM, agent self-service, integrations
TrainingNot started
Onboarding, format, assessment, eLearning, QM integration
Reporting & InsightsNot started
Real-time & historical reporting, analytics, BI, CRM
" } }, - "d1318d0516724e41b98ac4bc97d5501f": { + "4577562ceab14ac59502bf3d61b3558b": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Background & Organization: Lines of business & scope", + "last_changed_at": "", + "layout": "IPY_MODEL_bad488e019f4405ba4b6e26fb839b045", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "45a62567adda4b4aabaf537745a299f7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4bf057077ef54111826b01e09cb0c2d7": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4ed8a64da5d043d49311e8adec77d074": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "51e582f774904655b799a688e7297095": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "52d9e6ee9d2746e69d60cc3af8f5b01d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "59d4a779c9eb46a69d092e98bcd5bc3e": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Routing & Automation: Virtual agents & assist", + "last_changed_at": "", + "layout": "IPY_MODEL_51e582f774904655b799a688e7297095", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "5a26381ab5a546edb671524ffec3093d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5b191db98ba842e59c70203d4442805b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5d3978523d1a4831ad357ea51fc29500": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5ea3a44bff7c4ce4a63937abc5abf078": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "65eecaf612d54035945e88ac4e13134b": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6a6c72a002a14996806931189dc2a762": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6a9fc0b7b44a4432b204046b1f105dd1": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "6c1b7167e9b1427b88bc6294a069c64e": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -4756,7 +3546,7 @@ "disabled": false, "hidden": false, "label": "Training — status", - "layout": "IPY_MODEL_8b204e5fca814a74874b84ceef255495", + "layout": "IPY_MODEL_79777a72dd864de0a53e34d2c8ac3fb4", "layout_path": null, "position": "sidebar", "render_slot_id": null, @@ -4767,60 +3557,7 @@ "value": "Not started" } }, - "d305544e68144c3ab7b149512b6a568d": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "d9f9a188dd4f48f7a30fcb41e78e8257": { + "6d51502a805c4ad0a84412e31231a8dc": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -4840,9 +3577,9 @@ "cell_id": "", "disabled": false, "hidden": false, - "label": "Channels: Voice & video metrics", + "label": "Background & Organization: Decision-making & priorities", "last_changed_at": "", - "layout": "IPY_MODEL_8eaf41bd51594842a7ac8274d5f5f70b", + "layout": "IPY_MODEL_31ce043e86034f2c89ab70982964edba", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -4854,7 +3591,69 @@ "value": false } }, - "dfe2dc69f8934f73b60c9f253afb3c08": { + "6d8dd95bf76f448ca63954842e0c252d": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.text.TextInputWidget", + "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Reporting & Insights — notes", + "layout": "IPY_MODEL_8126e4c8e8df478f8efd609ccb119784", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "" + } + }, + "70f6f83bca334c7688b05d8a09764cb6": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.text.TextInputWidget", + "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "CX Strategy — notes", + "layout": "IPY_MODEL_e4b85b0d4e184c4094afa3f4db7454a2", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "" + } + }, + "726d90aecdba4272ad0c4fbb809f48ed": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -4907,7 +3706,7 @@ "width": null } }, - "e74f98220a094696b7e2525782c140d0": { + "77fc6178e65e4d7ca76c8adb00f2c115": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -4927,9 +3726,9 @@ "cell_id": "", "disabled": false, "hidden": false, - "label": "Background & Organization: Lines of business & scope", + "label": "Channels: Digital channels", "last_changed_at": "", - "layout": "IPY_MODEL_8e5fb4e5e45542e8a283674969277d5d", + "layout": "IPY_MODEL_40d26c433bd2492a89755d08a1214a27", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -4941,60 +3740,7 @@ "value": false } }, - "e82e2575b84843408f189ddcc5d8ef7b": { - "model_module": "@jupyter-widgets/base", - "model_module_version": "2.0.0", - "model_name": "LayoutModel", - "state": { - "_model_module": "@jupyter-widgets/base", - "_model_module_version": "2.0.0", - "_model_name": "LayoutModel", - "_view_count": null, - "_view_module": "@jupyter-widgets/base", - "_view_module_version": "2.0.0", - "_view_name": "LayoutView", - "align_content": null, - "align_items": null, - "align_self": null, - "border_bottom": null, - "border_left": null, - "border_right": null, - "border_top": null, - "bottom": null, - "display": null, - "flex": null, - "flex_flow": null, - "grid_area": null, - "grid_auto_columns": null, - "grid_auto_flow": null, - "grid_auto_rows": null, - "grid_column": null, - "grid_gap": null, - "grid_row": null, - "grid_template_areas": null, - "grid_template_columns": null, - "grid_template_rows": null, - "height": null, - "justify_content": null, - "justify_items": null, - "left": null, - "margin": null, - "max_height": null, - "max_width": null, - "min_height": null, - "min_width": null, - "object_fit": null, - "object_position": null, - "order": null, - "overflow": null, - "padding": null, - "right": null, - "top": null, - "visibility": null, - "width": null - } - }, - "ec1be2c8173343f6b2829c950f4bffc8": { + "78e6ef2a955749668cd65184d203e3b9": { "model_module": "@jupyter-widgets/controls", "model_module_version": "2.0.0", "model_name": "HTMLStyleModel", @@ -5012,7 +3758,7 @@ "text_color": null } }, - "ed27b6ab00fb439bafd27011900a74b3": { + "79777a72dd864de0a53e34d2c8ac3fb4": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -5065,7 +3811,641 @@ "width": null } }, - "f1920f6a825349f1be5e9cd1a22b0708": { + "7f80da0508a4497688d605d037802248": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7fc16187077848d59babbd224d3ceb4c": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7fec23b1406644df93028629ae246e38": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8126e4c8e8df478f8efd609ccb119784": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8193b4d5cb2b4f32853bc9c057f3af1e": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Channels: Inbound contact reasons", + "last_changed_at": "", + "layout": "IPY_MODEL_5d3978523d1a4831ad357ea51fc29500", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "8368207a3d684c9b955efb9922b8e7b9": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "Agent & Supervisor Environment — status", + "layout": "IPY_MODEL_8ad428b804264804912f8a352f1d6eb6", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "85f77e3f4ac341ea8465de7ed8e60362": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8633016a74bf45edbcab256647887d2e": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8686a07e5bd840f181b8fb1295280bc0": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Workforce Engagement: Workforce management", + "last_changed_at": "", + "layout": "IPY_MODEL_c03be02e32da4d1590130e25e7a660da", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "8ad428b804264804912f8a352f1d6eb6": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "96e8b19e7f334299a6b55590bb9161b2": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Background & Organization: Org & reporting structure", + "last_changed_at": "", + "layout": "IPY_MODEL_7fec23b1406644df93028629ae246e38", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "a451eea831e647c397da7b1450a4a92f": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "Background & Organization — status", + "layout": "IPY_MODEL_65eecaf612d54035945e88ac4e13134b", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "a8206b8bd1694936af419af888e57e84": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Routing & Automation: Self-service & IVR", + "last_changed_at": "", + "layout": "IPY_MODEL_8633016a74bf45edbcab256647887d2e", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "ad71bc9d32cb4684af8498f125a65bdf": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b3115751d9fa4beabb2f152ed21a0ae3": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -5085,7 +4465,7 @@ "disabled": false, "hidden": false, "label": "Channels — notes", - "layout": "IPY_MODEL_cda4056ee6f1451696fbd29c12b8f3f7", + "layout": "IPY_MODEL_2fbc83509c604715ba49f524282af285", "layout_path": null, "position": "sidebar", "render_slot_id": null, @@ -5096,7 +4476,7 @@ "value": "" } }, - "f2fc5e48221a411794915f937f7ba4b2": { + "b48d623d4ba04ed29b206f4e1cf7c40b": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -5149,7 +4529,7 @@ "width": null } }, - "f970d4839d8f4511ab9e995f0da3e706": { + "b70b532c7b0942f792415fc6c0fe5fa7": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -5202,7 +4582,38 @@ "width": null } }, - "fa22be1733f348b69c788b81315f5fd1": { + "b72bd8acfd374276b0ebdd203075c9b6": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.text.TextInputWidget", + "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Routing & Automation — notes", + "layout": "IPY_MODEL_b96a9d0c486b47699811834fae47a695", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "" + } + }, + "b96a9d0c486b47699811834fae47a695": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -5255,7 +4666,7 @@ "width": null } }, - "fa59fa350540437ab65cddd0b948f6b1": { + "bad488e019f4405ba4b6e26fb839b045": { "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "model_name": "LayoutModel", @@ -5308,7 +4719,426 @@ "width": null } }, - "fe8ea7220e28420aa3f4b8901b51a2d9": { + "bdad679e97ff4eb3ad07cbe4a8643a58": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c03be02e32da4d1590130e25e7a660da": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c20bedce4b4b4854a6c14bafc87295fc": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "c7e7ba21fe704e618b6244464034b9d9": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "ca66db1b382a49d4af0b4ce9593e6e70": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Reporting & Insights: Reporting", + "last_changed_at": "", + "layout": "IPY_MODEL_4ed8a64da5d043d49311e8adec77d074", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "d04723c27a694c48965d347729954375": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Background & Organization: Channels supported", + "last_changed_at": "", + "layout": "IPY_MODEL_7f80da0508a4497688d605d037802248", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "d1022625168744a897229cff827f8392": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Background & Organization: Problems & causes today", + "last_changed_at": "", + "layout": "IPY_MODEL_1491ef06c9ea4b15b3c72de83b38a374", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "d5d6f1aa4fbd409699530cc1bca9b74d": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.text.TextInputWidget", + "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Background & Organization — notes", + "layout": "IPY_MODEL_f78c1d8dc95f44c09e4aa7e559750a51", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "" + } + }, + "d6fef173bf9e42179464b5034b9728e9": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "Workforce Engagement — status", + "layout": "IPY_MODEL_e1b875aa9a4348a18fe8a5d3412c5e12", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "d980c0367d404f7e9397b9b37021ffbd": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "Reporting & Insights — status", + "layout": "IPY_MODEL_c20bedce4b4b4854a6c14bafc87295fc", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "dafa8c55991946a187fe9d550de53414": { "model_module": "anywidget", "model_module_version": "~0.11.*", "model_name": "AnyModel", @@ -5330,7 +5160,7 @@ "hidden": false, "label": "CX Strategy: Continuous improvement", "last_changed_at": "", - "layout": "IPY_MODEL_f2fc5e48221a411794915f937f7ba4b2", + "layout": "IPY_MODEL_c7e7ba21fe704e618b6244464034b9d9", "layout_path": null, "n_toggles": 0, "position": "sidebar", @@ -5341,6 +5171,577 @@ "url_key": "", "value": false } + }, + "dfdc4e514e694492a37dcc756e7dc5b7": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Channels: Inbound context", + "last_changed_at": "", + "layout": "IPY_MODEL_194b98c3b1ab4c828036e196974cbbfa", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "e1b875aa9a4348a18fe8a5d3412c5e12": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "e4b85b0d4e184c4094afa3f4db7454a2": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "ea3fc8677a1c4aec8eca4f0bc1f7a5a8": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.text.TextInputWidget", + "_css": "\n .mljar-textinput-container {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n min-width: 120px;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: normal;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n box-sizing: border-box;\n }\n\n .mljar-textinput-top-label {\n padding-top: 6px;\n margin-bottom: 6px;\n text-align: left;\n width: 100%;\n font-weight: 600;\n }\n\n .mljar-textinput-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 10px;\n box-sizing: border-box;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n color: #0f172a;\n line-height: 1.4;\n\n appearance: none !important;\n background-color: #ffffff !important;\n }\n\n .mljar-textinput-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n }\n\n .mljar-textinput-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n @media (max-width: 768px) {\n .mljar-textinput-input {\n min-height: 44px;\n padding: 10px 12px;\n }\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-textinput-container\");\n\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-textinput-top-label\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-textinput-input\");\n\n container.appendChild(topLabel);\n container.appendChild(input);\n el.appendChild(container);\n\n let debounceTimer = null;\n\n input.addEventListener(\"input\", () => {\n if (model.get(\"disabled\")) return;\n model.set(\"value\", input.value);\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => model.save_changes(), 200);\n });\n\n function syncFromModel() {\n topLabel.innerHTML = model.get(\"label\") || \"Enter text\";\n input.value = model.get(\"value\") ?? \"\";\n\n const disabled = !!model.get(\"disabled\");\n input.disabled = disabled;\n\n const hidden = !!model.get(\"hidden\");\n container.style.display = hidden ? \"none\" : \"flex\";\n }\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n /*\n // ---- read cell id (no DOM modifications) ----\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Workforce Engagement — notes", + "layout": "IPY_MODEL_7fc16187077848d59babbd224d3ceb4c", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "" + } + }, + "ee709981f4454a96b98a9c9bb1e6d4ca": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Training: Onboarding & enablement", + "last_changed_at": "", + "layout": "IPY_MODEL_726d90aecdba4272ad0c4fbb809f48ed", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "f0aabb7f6d944dfa839728a33422d5c8": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Workforce Engagement: Agent self-service & integrations", + "last_changed_at": "", + "layout": "IPY_MODEL_b48d623d4ba04ed29b206f4e1cf7c40b", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "f0d9c25925fc45a8b1005234f675ace8": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Agent & Supervisor Environment: Desktop & applications", + "last_changed_at": "", + "layout": "IPY_MODEL_45a62567adda4b4aabaf537745a299f7", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "f0fae9e3698e4246ab05f98f02919d30": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Workforce Engagement: Call recording & Quality Management", + "last_changed_at": "", + "layout": "IPY_MODEL_6a9fc0b7b44a4432b204046b1f105dd1", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "f31201923cb44e409e1ea78501f97681": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.select.SelectWidget", + "_css": "\n .mljar-select-container {\n position: relative;\n display: flex;\n flex-direction: column;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n color: #0f172a;\n padding-left: 4px;\n padding-right: 4px;\n overflow: visible;\n }\n\n .mljar-select-label {\n padding-top: 6px;\n margin-bottom: 4px;\n font-weight: 600;\n }\n\n .mljar-select-control {\n position: relative;\n display: flex;\n align-items: center;\n cursor: default;\n overflow: visible;\n }\n\n .mljar-select-container.is-open {\n z-index: 20;\n }\n\n .mljar-select-widget-input {\n width: 100%;\n min-height: 40px;\n padding: 9px 36px 9px 10px;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-sizing: border-box;\n line-height: 1.4;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n appearance: none !important;\n background-color: #ffffff !important;\n color: #0f172a !important;\n cursor: default;\n }\n\n .mljar-select-widget-input:focus {\n outline: none;\n border-color: #007bff;\n box-shadow: none;\n cursor: text;\n }\n\n .mljar-select-caret {\n position: absolute;\n right: 12px;\n top: 50%;\n width: 8px;\n height: 8px;\n border-right: 1.5px solid #0f172a;\n border-bottom: 1.5px solid #0f172a;\n transform: translateY(-65%) rotate(45deg);\n pointer-events: auto;\n opacity: 0.5;\n transition: transform 0.18s ease, opacity 0.18s ease;\n }\n\n .mljar-select-container.is-open .mljar-select-caret {\n opacity: 1;\n transform: translateY(-35%) rotate(225deg);\n }\n\n .mljar-select-dropdown {\n display: none;\n position: fixed;\n z-index: 10000;\n border: 1px solid #cfd1d5;\n border-radius: 6px;\n background: #ffffff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);\n overflow: hidden;\n }\n\n .mljar-select-list {\n max-height: 260px;\n overflow-y: auto;\n }\n\n .mljar-select-option {\n display: block;\n width: 100%;\n padding: 9px 10px;\n border: 0;\n background: transparent;\n color: #0f172a;\n text-align: left;\n cursor: pointer;\n font: inherit;\n transition: background-color 0.14s ease, color 0.14s ease;\n }\n\n .mljar-select-option:hover {\n background: #f3f3f4;\n }\n\n .mljar-select-option:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-option.is-selected {\n background: #e6f2ff;\n color: #007bff;\n font-weight: 600;\n }\n\n .mljar-select-option.is-selected:hover,\n .mljar-select-option.is-selected:active {\n background: #e6f2ff;\n color: #007bff;\n }\n\n .mljar-select-empty {\n display: none;\n padding: 10px;\n color: #616673;\n font-size: 0.95em;\n }\n\n .mljar-select-widget-input:disabled {\n background: #f5f5f5;\n color: #888;\n cursor: not-allowed;\n }\n\n .mljar-select-control.is-disabled .mljar-select-caret {\n opacity: 0.45;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const normalize = value => String(value ?? \"\").toLowerCase().trim();\n const getChoices = () =>\n Array.isArray(model.get(\"choices\")) ? [...model.get(\"choices\")] : [];\n const isDisabled = () => !!model.get(\"disabled\");\n const isHidden = () => !!model.get(\"hidden\");\n\n const container = document.createElement(\"div\");\n container.classList.add(\"mljar-select-container\");\n\n if (model.get(\"label\")) {\n const topLabel = document.createElement(\"div\");\n topLabel.classList.add(\"mljar-select-label\");\n topLabel.innerHTML = model.get(\"label\");\n container.appendChild(topLabel);\n }\n\n const control = document.createElement(\"div\");\n control.classList.add(\"mljar-select-control\");\n\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.classList.add(\"mljar-select-widget-input\");\n input.autocomplete = \"off\";\n input.spellcheck = false;\n\n const caret = document.createElement(\"div\");\n caret.classList.add(\"mljar-select-caret\");\n\n control.appendChild(input);\n control.appendChild(caret);\n\n const dropdown = document.createElement(\"div\");\n dropdown.classList.add(\"mljar-select-dropdown\");\n\n const list = document.createElement(\"div\");\n list.classList.add(\"mljar-select-list\");\n\n const emptyState = document.createElement(\"div\");\n emptyState.classList.add(\"mljar-select-empty\");\n emptyState.textContent = \"No matches\";\n\n dropdown.appendChild(list);\n dropdown.appendChild(emptyState);\n\n container.appendChild(control);\n el.appendChild(container);\n\n let isOpen = false;\n let filteredChoices = [];\n let lastCommittedValue = \"\";\n let isEditing = false;\n document.body.appendChild(dropdown);\n\n const updateDropdownPosition = () => {\n if (!isOpen) {\n return;\n }\n const rect = control.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 6}px`;\n dropdown.style.left = `${rect.left}px`;\n dropdown.style.width = `${rect.width}px`;\n };\n\n const setOpen = next => {\n if (isDisabled()) {\n isOpen = false;\n } else {\n isOpen = !!next;\n }\n container.classList.toggle(\"is-open\", isOpen);\n dropdown.style.display = isOpen ? \"block\" : \"none\";\n if (isOpen) {\n updateDropdownPosition();\n }\n };\n\n const updateDisabledState = () => {\n const disabled = isDisabled();\n input.disabled = disabled;\n control.classList.toggle(\"is-disabled\", disabled);\n };\n\n const updateHiddenState = () => {\n container.style.display = isHidden() ? \"none\" : \"\";\n };\n\n const syncInputWithValue = () => {\n const value = model.get(\"value\") || \"\";\n lastCommittedValue = value;\n if (!isEditing) {\n input.value = value;\n }\n };\n\n const filterChoices = query => {\n const normalizedQuery = normalize(query);\n const allChoices = getChoices();\n if (!normalizedQuery) {\n return allChoices;\n }\n return allChoices.filter(choice =>\n normalize(choice).includes(normalizedQuery)\n );\n };\n\n const renderList = () => {\n list.innerHTML = \"\";\n filteredChoices.forEach(choice => {\n const option = document.createElement(\"button\");\n option.type = \"button\";\n option.classList.add(\"mljar-select-option\");\n if (choice === model.get(\"value\")) {\n option.classList.add(\"is-selected\");\n }\n option.textContent = choice;\n option.addEventListener(\"mousedown\", event => {\n event.preventDefault();\n event.stopPropagation();\n model.set(\"value\", choice);\n model.save_changes();\n isEditing = false;\n syncInputWithValue();\n renderList();\n setOpen(false);\n });\n list.appendChild(option);\n });\n\n const hasMatches = filteredChoices.length > 0;\n list.style.display = hasMatches ? \"block\" : \"none\";\n emptyState.style.display = hasMatches ? \"none\" : \"block\";\n };\n\n const refreshList = () => {\n filteredChoices = filterChoices(input.value);\n renderList();\n };\n\n const openWithCurrentQuery = () => {\n isEditing = true;\n input.value = \"\";\n refreshList();\n setOpen(true);\n };\n\n const closeDropdown = () => {\n isEditing = false;\n setOpen(false);\n input.value = lastCommittedValue;\n };\n\n control.addEventListener(\"click\", event => {\n event.stopPropagation();\n if (isDisabled()) {\n return;\n }\n if (event.target === caret && isOpen) {\n closeDropdown();\n input.blur();\n return;\n }\n openWithCurrentQuery();\n input.focus();\n });\n\n input.addEventListener(\"input\", () => {\n if (isDisabled()) {\n return;\n }\n refreshList();\n setOpen(true);\n });\n\n input.addEventListener(\"focus\", () => {\n if (isDisabled()) {\n return;\n }\n openWithCurrentQuery();\n });\n\n input.addEventListener(\"blur\", () => {\n isEditing = false;\n input.value = lastCommittedValue;\n });\n\n const handleDocumentClick = event => {\n if (!container.contains(event.target) && !dropdown.contains(event.target)) {\n closeDropdown();\n }\n };\n\n document.addEventListener(\"click\", handleDocumentClick);\n window.addEventListener(\"resize\", updateDropdownPosition);\n document.addEventListener(\"scroll\", updateDropdownPosition, true);\n\n model.on(\"change:value\", () => {\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:choices\", () => {\n const choices = getChoices();\n if (!choices.includes(model.get(\"value\")) && choices.length > 0) {\n model.set(\"value\", choices[0]);\n model.save_changes();\n return;\n }\n syncInputWithValue();\n refreshList();\n });\n\n model.on(\"change:disabled\", () => {\n updateDisabledState();\n if (isDisabled()) {\n closeDropdown();\n }\n });\n\n model.on(\"change:hidden\", () => {\n updateHiddenState();\n });\n\n updateDisabledState();\n updateHiddenState();\n syncInputWithValue();\n refreshList();\n setOpen(false);\n\n return () => {\n dropdown.remove();\n document.removeEventListener(\"click\", handleDocumentClick);\n window.removeEventListener(\"resize\", updateDropdownPosition);\n document.removeEventListener(\"scroll\", updateDropdownPosition, true);\n };\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "cell_id": "", + "choices": [ + "Not started", + "In progress", + "Complete", + "Skipped" + ], + "disabled": false, + "hidden": false, + "label": "CX Strategy — status", + "layout": "IPY_MODEL_ff74b3278d63442db94751da76210d83", + "layout_path": null, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": "Not started" + } + }, + "f669b4e9c5164f8fb734f4f3060e19ea": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "CX Strategy: Insight & Voice of Customer", + "last_changed_at": "", + "layout": "IPY_MODEL_2e29bd2928674e31b3fd1e2d485a29ed", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "f756ed14bebb4b1787445e09b080dd1d": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "f78c1d8dc95f44c09e4aa7e559750a51": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "fc04710798de44fb99bc55b34300c448": { + "model_module": "anywidget", + "model_module_version": "~0.11.*", + "model_name": "AnyModel", + "state": { + "_anywidget_id": "mercury.checkbox.CheckboxWidget", + "_css": "\n .mljar-checkbox-container {\n display: inline-flex;\n align-items: center;\n gap: 10px;\n cursor: pointer;\n user-select: none;\n -webkit-tap-highlight-color: transparent;\n font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n color: #0f172a;\n padding-left: 5px;\n }\n .mljar-checkbox-container.is-disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n .mljar-checkbox-input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n }\n\n .mljar-checkbox-input:focus-visible + .mljar-checkbox-control {\n box-shadow: inset 0 0 0 2px #007bff;\n }\n\n .mljar-checkbox-label {\n font-size: 14px;\n line-height: 1.2;\n padding-top: 2px;\n }\n\n /* --- Toggle style (15% smaller) --- */\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control {\n position: relative;\n width: 34px;\n height: 19px;\n border-radius: 999px;\n background: #f1f1f2;\n border: 1px solid #cfd1d5;\n transition: background 150ms ease, border-color 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control {\n background: #007bff;\n border-color: #007bff;\n }\n .mljar-checkbox-container.is-toggle .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n top: 2px;\n left: 2px;\n width: 15px;\n height: 15px;\n border-radius: 50%;\n background: #ffffff;\n box-shadow: 0 1px 2px rgba(0,0,0,0.12), 0 0 0 1px rgba(0,0,0,0.04);\n transition: transform 150ms ease;\n }\n .mljar-checkbox-container.is-toggle.is-checked .mljar-checkbox-control::after {\n transform: translateX(15px);\n }\n\n /* --- Classic box style --- */\n .mljar-checkbox-container.is-box .mljar-checkbox-control {\n width: 16px;\n height: 16px;\n border-radius: 4px;\n border: 1px solid #cfd1d5;\n background: #ffffff;\n display: inline-block;\n position: relative;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control {\n border-color: #007bff;\n background: #007bff;\n }\n .mljar-checkbox-container.is-box.is-checked .mljar-checkbox-control::after {\n content: \"\";\n position: absolute;\n left: 4px;\n top: 0px;\n width: 5px;\n height: 10px;\n border: solid #fff;\n border-width: 0 2px 2px 0;\n transform: rotate(45deg);\n }\n\n .mljar-checkbox-container:not(.is-disabled):hover .mljar-checkbox-control {\n border-color: #007bff;\n background: #f3f3f4;\n }\n ", + "_dom_classes": [], + "_esm": "\n function render({ model, el }) {\n const container = document.createElement(\"label\");\n container.classList.add(\"mljar-checkbox-container\");\n\n const input = document.createElement(\"input\");\n input.type = \"checkbox\";\n input.classList.add(\"mljar-checkbox-input\");\n\n const control = document.createElement(\"span\");\n control.classList.add(\"mljar-checkbox-control\");\n\n const text = document.createElement(\"span\");\n text.classList.add(\"mljar-checkbox-label\");\n\n container.appendChild(input);\n container.appendChild(control);\n container.appendChild(text);\n el.appendChild(container);\n\n function syncFromModel() {\n // appearance\n const a = model.get(\"appearance\") || \"toggle\";\n container.classList.remove(\"is-toggle\",\"is-box\");\n container.classList.add(`is-${a}`);\n input.setAttribute(\"role\", a === \"toggle\" ? \"switch\" : \"checkbox\");\n\n // value\n const v = !!model.get(\"value\");\n if (input.checked !== v) {\n input.checked = v;\n input.setAttribute(\"aria-checked\", String(v));\n }\n container.classList.toggle(\"is-checked\", v);\n\n // disabled\n const d = !!model.get(\"disabled\");\n input.disabled = d;\n container.classList.toggle(\"is-disabled\", d);\n\n // label\n text.textContent = model.get(\"label\") || \"\";\n\n // hidden (exists but not visible)\n container.style.display = model.get(\"hidden\") ? \"none\" : \"inline-flex\";\n }\n\n input.addEventListener(\"change\", () => {\n if (model.get(\"disabled\")) return;\n\n const v = input.checked;\n if (model.get(\"value\") !== v) {\n model.set(\"value\", v);\n model.set(\"last_changed_at\", new Date().toISOString());\n model.set(\"n_toggles\", (model.get(\"n_toggles\") || 0) + 1);\n model.save_changes();\n // model.send({ type: \"changed\", value: v });\n }\n });\n\n model.on(\"change:value\", syncFromModel);\n model.on(\"change:disabled\", syncFromModel);\n model.on(\"change:appearance\", syncFromModel);\n model.on(\"change:label\", syncFromModel);\n model.on(\"change:hidden\", syncFromModel);\n\n syncFromModel();\n\n // ---- read cell id (no DOM modifications) ----\n /*\n const ID_ATTR = \"data-cell-id\";\n const hostWithId = el.closest(`[${ID_ATTR}]`);\n const cellId = hostWithId ? hostWithId.getAttribute(ID_ATTR) : null;\n\n if (cellId) {\n model.set(\"cell_id\", cellId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: cellId });\n } else {\n const mo = new MutationObserver(() => {\n const host = el.closest(`[${ID_ATTR}]`);\n const newId = host?.getAttribute(ID_ATTR);\n \n if (newId) {\n model.set(\"cell_id\", newId);\n model.save_changes();\n model.send({ type: \"cell_id_detected\", value: newId });\n mo.disconnect();\n }\n });\n mo.observe(document.body, { attributes: true, subtree: true, attributeFilter: [ID_ATTR] });\n }\n */\n }\n export default { render };\n ", + "_model_module": "anywidget", + "_model_module_version": "~0.11.*", + "_model_name": "AnyModel", + "_view_count": null, + "_view_module": "anywidget", + "_view_module_version": "~0.11.*", + "_view_name": "AnyView", + "appearance": "box", + "cell_id": "", + "disabled": false, + "hidden": false, + "label": "Agent & Supervisor Environment: Locations & endpoints", + "last_changed_at": "", + "layout": "IPY_MODEL_bdad679e97ff4eb3ad07cbe4a8643a58", + "layout_path": null, + "n_toggles": 0, + "position": "sidebar", + "render_slot_id": null, + "source_cell_id": null, + "tabbable": null, + "tooltip": null, + "url_key": "", + "value": false + } + }, + "ff74b3278d63442db94751da76210d83": { + "model_module": "@jupyter-widgets/base", + "model_module_version": "2.0.0", + "model_name": "LayoutModel", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "2.0.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "2.0.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border_bottom": null, + "border_left": null, + "border_right": null, + "border_top": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } } }, "version_major": 2, diff --git a/studies/202607_CX_Discovery_Workshop/pyproject.toml b/studies/202607_CX_Discovery_Workshop/pyproject.toml index e9ec9f9..5cfb702 100644 --- a/studies/202607_CX_Discovery_Workshop/pyproject.toml +++ b/studies/202607_CX_Discovery_Workshop/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "jupyterlab>=4.0", "ipywidgets>=8.0", "nbconvert>=7", + "nbformat>=5.9", "tabulate>=0.9", ] diff --git a/studies/202607_CX_Discovery_Workshop/scripts/build_notebook.py b/studies/202607_CX_Discovery_Workshop/scripts/build_notebook.py deleted file mode 100644 index 71edfae..0000000 --- a/studies/202607_CX_Discovery_Workshop/scripts/build_notebook.py +++ /dev/null @@ -1,362 +0,0 @@ -"""Generate notebooks/cx_discovery.ipynb from source cell text. - -The discovery notebook has ~42 Mercury widgets (a status selector + a notes -box per topic, plus a checkbox per sub-topic). Hand-maintaining that JSON is -error-prone, so the notebook is *generated* from this script — the cell -sources live here as readable Python strings and nbformat writes valid JSON. - -Re-run after editing any cell: python scripts/build_notebook.py -Then execute + export as usual (nbconvert / scripts/export_report.py). - -This is a build tool, not the engine — all study logic stays in discoverylib. -""" - -from __future__ import annotations - -import pathlib - -import nbformat as nbf - -ROOT = pathlib.Path(__file__).resolve().parent.parent -OUT = ROOT / "notebooks" / "cx_discovery.ipynb" - - -# ── Cell sources ───────────────────────────────────────────────────── - -MD_TITLE = """\ -# CX Exploration & Discovery Workshop - -The live visual for a discovery session. On screen the client sees the -**topic board** — each topic, its one-line scope, and a status glyph — the -**live sub-topic checklist** for whatever we're discussing now, and a -**progress headline** ("3/8 topics complete"). You drive the conversation -from the question script (which stays backstage); the client is never shown -a wall of questions. - -**This notebook is the deliverable.** Serve it with -`mercury --working-dir .` and share that screen; mark each topic's status in -the sidebar as the discussion moves and tick sub-topics as you cover them — -the board and progress bar update live. Capture answers in the per-topic -notes boxes. Afterward, `python scripts/export_report.py` writes an -LLM-readable report source (notes + status + progress as markdown and JSON) -to feed the survey write-up or a downstream business-case study. - -All content and logic live in `discoverylib/` — the notebook only arranges -and renders them. - -Confidence legend: 🟢 confirmed · 🟡 estimated · 🔴 unknown — used in the -captured notes, not on the client-facing board.""" - - -SETUP = '''\ -# ── Setup ────────────────────────────────────────────────────────── -import sys, pathlib -_ROOT = pathlib.Path.cwd() -if not (_ROOT / "discoverylib").exists(): # notebook lives in notebooks/ - _ROOT = _ROOT.parent -sys.path.insert(0, str(_ROOT)) - -import html as _html - -import mercury as mr - -# Single source of truth — the topic bank and all status/progress logic -# live in the library; only presentation (and Mercury widgets) lives here. -from discoverylib import ( - TOPICS, STATUSES, STATUS_LABEL, STATUS_GLYPH, STATUS_COLOR, - build_session, subtopic_checklist, subtopic_id, session_json, -) -from discoverylib.staging import backstage - -# ── Brand palette (docs/brand.md, light theme) ───────────────────── -NAVY, INK, MUTED = "#151d2c", "#2e404d", "#586671" -BLUE, GREEN, LINE = "#0072bc", "#00a34c", "#e2e6e9" -CARD_BG, HAIRLINE = "#f8f8f8", "#d5d9db" -FONT = "Georgia, 'Times New Roman', serif" -BODY_FONT = "Arial, 'Helvetica Neue', Helvetica, sans-serif" - - -def esc(s): - return _html.escape(str(s)) - - -backstage(f"discoverylib loaded — {len(TOPICS)} topics · " - f"{sum(len(t.subtopics) for t in TOPICS)} sub-topics · " - f"{sum(t.prompt_count for t in TOPICS)} prompts")''' - - -MD_HOWTO = """\ -## How to run this session - -- **Sidebar** — one **status** selector and a **notes** box per topic, plus a - **sub-topic checkbox** for each thread. As the conversation moves, set the - topic you're on to *In progress*, tick sub-topics as you cover them, mark - the topic *Complete* (or *Skipped*) when you move on, and jot answers in its - notes box. -- **Stage** (this page) — the client-facing board and progress bar below - re-render on every change. -- **Backstage** (JupyterLab / the export) — the facilitator question script and - the captured-notes appendix. Neither shows on the Mercury stage.""" - - -# The widget block is generated from the topic bank so it stays DRY and -# can never drift from discoverylib. Widgets ONLY — no other output -# (Mercury leaks stray widget-cell output into the sidebar). -WIDGETS = '''\ -# ── Session controls (Mercury sidebar — widgets ONLY, no other output) ─ -# Generated from the topic bank: per topic a status selector + notes box, -# per sub-topic a checkbox. Mercury re-runs only cells BELOW this one, so -# every .value is read in the next cell down — never here. -# -# _status_w[topic_key] -> Select (Not started / In progress / …) -# _notes_w[topic_key] -> TextInput (captured answers, backstage) -# _sub_w[(topic_key, sub)] -> CheckBox (covered?) -# Labels are distinct per widget, so Mercury's label-keyed widget cache -# never collides across topics/sub-topics. -_status_w, _notes_w, _sub_w = {}, {}, {} - -for _t in TOPICS: - _status_w[_t.key] = mr.Select( - label=f"{_t.title} — status", - value=STATUS_LABEL[STATUSES[0]], - choices=[STATUS_LABEL[s] for s in STATUSES], - ) - for _st in _t.subtopics: - _sub_w[(_t.key, _st.key)] = mr.CheckBox( - value=False, appearance="box", - label=f"{_t.title}: {_st.title}") - _notes_w[_t.key] = mr.TextInput( - label=f"{_t.title} — notes", value="")''' - - -STATE = '''\ -# ── Session state (re-runs on any sidebar change) ─────────────────── -# Read every widget .value and rebuild the session via the engine. -_LABEL_TO_STATUS = {STATUS_LABEL[s]: s for s in STATUSES} - -STATUS_BY_TOPIC = {k: _LABEL_TO_STATUS.get(str(w.value), STATUSES[0]) - for k, w in _status_w.items()} -NOTES_BY_TOPIC = {k: str(w.value) for k, w in _notes_w.items()} -DONE_SUBTOPICS = {subtopic_id(tk, sk) - for (tk, sk), w in _sub_w.items() if bool(w.value)} - -SESSION = build_session(STATUS_BY_TOPIC, NOTES_BY_TOPIC, DONE_SUBTOPICS) -PROGRESS = SESSION["progress"] - -# One curated line on stage; full echo backstage. -print(f"{PROGRESS.label} · {PROGRESS.resolved}/{PROGRESS.total} resolved · " - f"agenda ~{SESSION['agenda_minutes']} min") -backstage("status: " + ", ".join(f"{ts.key}={ts.status}" for ts in SESSION["topics"]))''' - - -# The client-facing board. Pure HTML string built from SESSION; rendered -# with mr.Markdown so it shows on the Mercury stage (and in exports). -BOARD = '''\ -# ── Stage: the client-facing topic board + progress ───────────────── -def _progress_bar(frac, completed, total): - pct = max(0.0, min(1.0, frac)) * 100 - return ( - f'
' - f'
' - f'
' - f'
' - f'{completed} of {total} topics complete
') - - -def _topic_row(ts, is_active): - ring = f"2px solid {BLUE}" if is_active else f"1px solid {HAIRLINE}" - bg = "#eef5fb" if is_active else CARD_BG - active_tag = (f'discussing now →' if is_active else "") - sub = "" - if is_active and ts.subtopics_total: - items = [] - for it in subtopic_checklist(_ACTIVE_TOPIC, DONE_SUBTOPICS): - mark = "✓" if it.done else "○" - col = GREEN if it.done else MUTED - wt = "600" if it.done else "400" - items.append( - f'
  • ' - f'{mark}' - f'{esc(it.title)}
  • ') - sub = (f'
      ' - f'{"".join(items)}
    ') - return ( - f'
    ' - f'
    ' - f'{ts.glyph}' - f'{esc(ts.title)}' - f'{active_tag}' - f'' - f'{esc(ts.status_label)}
    ' - f'
    ' - f'{esc(ts.scope)}
    ' - f'{sub}
    ') - - -_ACTIVE_TOPIC = SESSION["active_topic"] -_rows = "".join(_topic_row(ts, ts.key == SESSION["active_topic_key"]) - for ts in SESSION["topics"]) -_header = ( - f'
    ' - f'CX Discovery — topics
    ' - f'
    ' - f'{len(SESSION["topics"])} topics · ~{SESSION["agenda_minutes"]} minutes
    ') - -_board_html = ( - f'
    {_header}' - f'{_progress_bar(PROGRESS.fraction, PROGRESS.completed, PROGRESS.total)}' - f'{_rows}
    ') -# Assign to _ so the bare-expression repr doesn't render a second copy. -_ = mr.Markdown(text=_board_html)''' - - -MD_SCRIPT = """\ -## Facilitator question script (backstage) - -The prompts below render in JupyterLab and in the exports — **not** on the -Mercury stage. They are your running order; ask them conversationally and let -the topics expand or drop as the client answers. Tick each sub-topic in the -sidebar as you cover it.""" - - -SCRIPT = '''\ -# ── Facilitator question script — backstage only ──────────────────── -# Renders in JupyterLab and the exports; hidden on the Mercury stage. -_lines = ["\\n# CX Discovery — facilitation script\\n"] -for _t in TOPICS: - _lines.append(f"\\n## {_t.title} · ~{_t.minutes} min") - _lines.append(f"_{_t.scope}_\\n") - for _st in _t.subtopics: - _lines.append(f"\\n**{_st.title}** — `{subtopic_id(_t.key, _st.key)}`") - for _p in _st.prompts: - _lines.append(f" - {_p}") -backstage("\\n".join(_lines))''' - - -MD_GATE = """\ -## Verification & assertions - -Engine pins use explicit values independent of the sidebar, so the gate tests -`discoverylib`, not the current session; structural ties hold at **any** widget -state. This cell must pass under headless `nbconvert --execute` — it is the -study's smoke test. Output renders backstage only.""" - - -GATE = '''\ -# ── Verification gate — must pass under headless nbconvert ─────────── -def _assert(cond, msg): - assert cond, msg - - -# Engine shape — independent of widget state (Pattern §4) -_assert(len(TOPICS) == 8, "expected 8 topics") -_assert(sum(len(t.subtopics) for t in TOPICS) == 26, "expected 26 sub-topics") -_assert(SESSION["agenda_minutes"] == 110, "agenda minutes drifted") -_assert(set(STATUS_BY_TOPIC) == {t.key for t in TOPICS}, "status keys ≠ topics") - -# Structural ties — hold at ANY sidebar setting -_p = SESSION["progress"] -_assert(_p.total == len(SESSION["topics"]) == 8, "progress total ≠ topic count") -_assert(_p.completed + _p.skipped + _p.in_progress + _p.not_started == _p.total, - "status counts don't sum to total") -_assert(0.0 <= _p.fraction <= 1.0, "fraction out of range") -_assert(_p.resolved == _p.completed + _p.skipped, "resolved identity broke") -for _ts in SESSION["topics"]: - _assert(0 <= _ts.subtopics_done <= _ts.subtopics_total, "sub-topic count out of range") - _assert(_ts.status in STATUSES, f"unknown status {_ts.status}") - -# Export payload is plain-JSON serializable and consistent with the session -import json as _json -_payload = session_json(SESSION, meta={"note": "gate check"}) -_json.dumps(_payload) # raises if not serializable -_assert(_payload["progress"]["completed"] == _p.completed, "export/session mismatch") -_assert(len(_payload["topics"]) == 8, "export lost a topic") - -backstage("All assertions passed.") -backstage(f" {_p.label} · {_p.resolved}/{_p.total} resolved")''' - - -MD_APPENDIX = """\ -## Data appendix — for the machines - -The captured session as a markdown table plus one JSON block of state, so the -exported report is complete LLM input for drafting the survey write-up or -seeding a business-case study. Renders **backstage** — hidden on the Mercury -stage.""" - - -APPENDIX = '''\ -# ── Data appendix — LLM-readable dump of the captured session ─────── -# Renders backstage only (JupyterLab / nbconvert exports). -import json as _json - -# Session metadata — edit these live for the client, or leave as defaults. -_META = { - "client": "", # 🟡 fill in for the engagement - "date": "", # 🟡 workshop date - "facilitator": "", # 🟡 -} - -backstage("\\n#### Captured session\\n") -_rows = ["| Topic | Status | Sub-topics | Notes |", - "|---|---|---:|---|"] -for _ts in SESSION["topics"]: - _note = _ts.notes.replace("|", "\\\\|").replace("\\n", " ") or "—" - _rows.append(f"| {_ts.title} | {_ts.status_label} | " - f"{_ts.subtopics_done}/{_ts.subtopics_total} | {_note} |") -backstage("\\n".join(_rows)) - -backstage(f"\\n{PROGRESS.label} · {PROGRESS.resolved}/{PROGRESS.total} resolved " - f"· agenda ~{SESSION['agenda_minutes']} min\\n") - -backstage("\\n#### Session state (JSON)\\n") -backstage("```json") -backstage(_json.dumps(session_json(SESSION, meta=_META), indent=2, ensure_ascii=False)) -backstage("```")''' - - -def md(source: str) -> nbf.NotebookNode: - return nbf.v4.new_markdown_cell(source) - - -def code(source: str) -> nbf.NotebookNode: - return nbf.v4.new_code_cell(source) - - -def build() -> nbf.NotebookNode: - nb = nbf.v4.new_notebook() - nb.cells = [ - md(MD_TITLE), - code(SETUP), - md(MD_HOWTO), - code(WIDGETS), - code(STATE), - code(BOARD), - md(MD_SCRIPT), - code(SCRIPT), - md(MD_GATE), - code(GATE), - md(MD_APPENDIX), - code(APPENDIX), - ] - nb.metadata = { - "kernelspec": {"display_name": "Python 3", "language": "python", - "name": "python3"}, - "language_info": {"name": "python"}, - } - return nb - - -def main() -> None: - OUT.parent.mkdir(parents=True, exist_ok=True) - nbf.write(build(), OUT) - print(f"wrote {OUT.relative_to(ROOT)} ({len(build().cells)} cells)") - - -if __name__ == "__main__": - main() diff --git a/studies/202607_CX_Discovery_Workshop/tests/conftest.py b/studies/202607_CX_Discovery_Workshop/tests/conftest.py index faed9ad..450f401 100644 --- a/studies/202607_CX_Discovery_Workshop/tests/conftest.py +++ b/studies/202607_CX_Discovery_Workshop/tests/conftest.py @@ -1,7 +1,52 @@ -"""Make discoverylib importable even without the study venv active (the -normal setup is ``pip install -e ".[dev]"`` into the study-local ``.venv/``).""" +"""Test plumbing: import path + the topic bank served from the notebook. + +The bank is CONTENT and lives in the notebook — the cell tagged +``topic-bank`` in ``notebooks/cx_discovery.ipynb``; ``.py`` files hold code +only. The fixtures below read that cell with nbformat and exec it, so +pytest pins the exact content the deliverable ships (no kernel needed — +the cell is self-contained by contract). + +The sys.path insert makes discoverylib importable even without the study +venv active (the normal setup is ``pip install -e ".[dev]"`` into the +study-local ``.venv/``). +""" + +from __future__ import annotations import pathlib import sys +from typing import Any -sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent)) +import pytest + +STUDY_ROOT = pathlib.Path(__file__).resolve().parent.parent +sys.path.insert(0, str(STUDY_ROOT)) + +NOTEBOOK = STUDY_ROOT / "notebooks" / "cx_discovery.ipynb" + + +@pytest.fixture(scope="session") +def topic_bank() -> dict[str, Any]: + """The executed namespace of the notebook's topic-bank cell.""" + import nbformat + + nb = nbformat.read(NOTEBOOK, as_version=4) + cells = [c for c in nb.cells if "topic-bank" in c.metadata.get("tags", [])] + assert len(cells) == 1, ( + f"expected exactly one cell tagged 'topic-bank' in {NOTEBOOK.name}, " + f"found {len(cells)}" + ) + ns: dict[str, Any] = {} + exec(compile(cells[0].source, f"{NOTEBOOK.name} [topic-bank]", "exec"), ns) + return ns + + +@pytest.fixture(scope="session") +def topics(topic_bank: dict[str, Any]) -> tuple[Any, ...]: + """The TOPICS tuple as the deliverable defines it.""" + return topic_bank["TOPICS"] # type: ignore[no-any-return] + + +@pytest.fixture(scope="session") +def topic_by_key(topics: tuple[Any, ...]) -> dict[str, Any]: + return {t.key: t for t in topics} diff --git a/studies/202607_CX_Discovery_Workshop/tests/test_session.py b/studies/202607_CX_Discovery_Workshop/tests/test_session.py index a23f42c..e14595a 100644 --- a/studies/202607_CX_Discovery_Workshop/tests/test_session.py +++ b/studies/202607_CX_Discovery_Workshop/tests/test_session.py @@ -1,7 +1,9 @@ """Session engine pins — status, progress, checklist, and export payload. Progress and status are this study's "numbers"; these are the hand-checked -acceptance values the in-notebook gate re-pins (Pattern §4). +acceptance values the in-notebook gate re-pins (Pattern §4). Every engine +function takes the bank as its first argument; the ``topics`` fixture +supplies the real bank from the notebook's topic-bank cell. """ from discoverylib import ( @@ -9,7 +11,6 @@ from discoverylib import ( IN_PROGRESS, NOT_STARTED, SKIPPED, - TOPIC_KEYS, active_topic_key, build_session, normalize_status, @@ -17,7 +18,6 @@ from discoverylib import ( session_json, subtopic_checklist, subtopic_id, - topic, ) @@ -27,8 +27,8 @@ def test_normalize_status_defaults_unknown(): assert normalize_status("garbage") == NOT_STARTED -def test_progress_all_not_started(): - p = progress({}) +def test_progress_all_not_started(topics): + p = progress(topics, {}) assert p.total == 8 assert (p.completed, p.skipped, p.in_progress, p.not_started) == (0, 0, 0, 8) assert p.fraction == 0.0 @@ -36,7 +36,7 @@ def test_progress_all_not_started(): assert p.label == "0/8 topics complete" -def test_progress_mixed_counts_and_fraction(): +def test_progress_mixed_counts_and_fraction(topics): status = { "background": COMPLETE, "cx_strategy": COMPLETE, @@ -44,25 +44,25 @@ def test_progress_mixed_counts_and_fraction(): "agent_environment": SKIPPED, # remaining four default to not_started } - p = progress(status) + p = progress(topics, status) assert (p.completed, p.skipped, p.in_progress, p.not_started) == (2, 1, 1, 4) assert p.resolved == 3 # complete + skipped assert p.fraction == 2 / 8 assert p.label == "2/8 topics complete" -def test_active_topic_prefers_in_progress_then_first_open(): +def test_active_topic_prefers_in_progress_then_first_open(topics): # in-progress wins even if a later topic is also in progress - assert active_topic_key({"channels": IN_PROGRESS}) == "channels" + assert active_topic_key(topics, {"channels": IN_PROGRESS}) == "channels" # no in-progress → first not-started in canonical order - assert active_topic_key({"background": COMPLETE}) == "cx_strategy" + assert active_topic_key(topics, {"background": COMPLETE}) == "cx_strategy" # everything resolved → None - all_done = {k: COMPLETE for k in TOPIC_KEYS} - assert active_topic_key(all_done) is None + all_done = {t.key: COMPLETE for t in topics} + assert active_topic_key(topics, all_done) is None -def test_subtopic_checklist_marks_done(): - t = topic("channels") +def test_subtopic_checklist_marks_done(topic_by_key): + t = topic_by_key["channels"] done = {subtopic_id("channels", "voice_metrics")} items = subtopic_checklist(t, done) assert len(items) == len(t.subtopics) @@ -71,12 +71,12 @@ def test_subtopic_checklist_marks_done(): assert by_key["inbound_context"] is False -def test_build_session_shape_and_subtopic_done_count(): +def test_build_session_shape_and_subtopic_done_count(topics, topic_by_key): status = {"channels": IN_PROGRESS, "background": COMPLETE} notes = {"channels": " 6 channels; voice ~70% "} done = {subtopic_id("channels", "voice_metrics"), subtopic_id("channels", "outbound")} - s = build_session(status, notes, done) + s = build_session(topics, status, notes, done) assert len(s["topics"]) == 8 assert s["active_topic_key"] == "channels" @@ -86,18 +86,18 @@ def test_build_session_shape_and_subtopic_done_count(): ch = next(ts for ts in s["topics"] if ts.key == "channels") assert ch.status == IN_PROGRESS assert ch.subtopics_done == 2 - assert ch.subtopics_total == len(topic("channels").subtopics) + assert ch.subtopics_total == len(topic_by_key["channels"].subtopics) assert ch.notes == "6 channels; voice ~70%" # trimmed bg = next(ts for ts in s["topics"] if ts.key == "background") assert bg.status == COMPLETE and bg.subtopics_done == 0 -def test_session_json_is_plain_and_complete(): +def test_session_json_is_plain_and_complete(topics): status = {"background": COMPLETE, "channels": IN_PROGRESS} notes = {"background": "3 LOBs; PCI in scope"} done = {subtopic_id("channels", "voice_metrics")} - payload = session_json(build_session(status, notes, done), + payload = session_json(build_session(topics, status, notes, done), meta={"client": "Acme", "date": "2026-07-19"}) assert payload["study"] == "202607_CX_Discovery_Workshop" diff --git a/studies/202607_CX_Discovery_Workshop/tests/test_topics.py b/studies/202607_CX_Discovery_Workshop/tests/test_topics.py index f318196..df82498 100644 --- a/studies/202607_CX_Discovery_Workshop/tests/test_topics.py +++ b/studies/202607_CX_Discovery_Workshop/tests/test_topics.py @@ -1,18 +1,20 @@ """Topic bank integrity — the verbatim facilitation record. -These pins are the anchor guard (Pattern §4): keys are stable identities -that captured notes and the JSON export key off, so renaming or reordering a -topic must be a deliberate, test-breaking act — never a silent drift. +The bank lives in the notebook's ``topic-bank`` cell (content is edited in +Jupyter, never in ``.py``); the ``topics`` fixture execs that cell, so +these pins guard the exact content the deliverable ships. Keys are stable +identities that captured notes and the JSON export key off, so renaming or +reordering a topic must be a deliberate, test-breaking act — never a +silent drift. """ -from discoverylib import TOPICS, TOPIC_KEYS, topic -from discoverylib.topics import TOPIC_BY_KEY +from discoverylib import Topic, agenda_minutes # ── Hand-checked shape (recount if you add/remove content) ─────────── -def test_topic_count_and_order(): - assert len(TOPICS) == 8 - assert TOPIC_KEYS == ( +def test_topic_count_and_order(topics): + assert len(topics) == 8 + assert tuple(t.key for t in topics) == ( "background", "cx_strategy", "channels", @@ -24,22 +26,27 @@ def test_topic_count_and_order(): ) -def test_subtopic_and_prompt_totals(): - assert sum(len(t.subtopics) for t in TOPICS) == 26 - assert sum(t.prompt_count for t in TOPICS) == 95 +def test_subtopic_and_prompt_totals(topics): + assert sum(len(t.subtopics) for t in topics) == 26 + assert sum(t.prompt_count for t in topics) == 95 -def test_agenda_minutes_sum(): - from discoverylib import agenda_minutes - assert agenda_minutes() == 110 - assert agenda_minutes() == sum(t.minutes for t in TOPICS) +def test_agenda_minutes_sum(topics): + assert agenda_minutes(topics) == 110 + assert agenda_minutes(topics) == sum(t.minutes for t in topics) + + +def test_bank_uses_library_schema(topics): + # The cell must build on discoverylib's dataclasses, not ad-hoc types, + # or the engine's TopicState/export contracts silently stop applying. + assert all(isinstance(t, Topic) for t in topics) # ── Structural invariants — hold for every topic ───────────────────── -def test_keys_unique_and_wellformed(): - keys = [t.key for t in TOPICS] +def test_keys_unique_and_wellformed(topics): + keys = [t.key for t in topics] assert len(keys) == len(set(keys)) # unique - for t in TOPICS: + for t in topics: assert t.key.replace("_", "").isalnum() # snake_case slug assert t.title and t.scope # client-facing text present assert t.minutes > 0 @@ -50,13 +57,13 @@ def test_keys_unique_and_wellformed(): assert st.prompts # no empty sub-topic -def test_lookup_helpers(): - assert topic("channels").title == "Channels" - assert TOPIC_BY_KEY["training"].minutes == 5 - assert TOPICS[0].key == "background" +def test_lookup(topics, topic_by_key): + assert topic_by_key["channels"].title == "Channels" + assert topic_by_key["training"].minutes == 5 + assert topics[0].key == "background" -def test_no_double_dollar_or_raw_markup_in_scope(): +def test_no_double_dollar_or_raw_markup_in_scope(topics): # scope lines render on stage HTML — keep them plain text. - for t in TOPICS: + for t in topics: assert "<" not in t.scope and ">" not in t.scope