/* ============================================================
   MySubaru Onboarding: case chapters, laid out natively in the
   portfolio's design language and registered into
   window.CASE_PANELS["mysubaru-onboarding"].

   Loads AFTER subaru.jsx, so it overrides that file's onboarding
   panels key by key while leaving the redesign and agentic-AI
   cases untouched. Preserved from subaru.jsx: the barriers bar
   chart and the 75% donut (ported here, same data), the four
   "why this project" signals, the STARLINK to MySubaru rebrand
   block, the meta grid, the North Star, and the kiosk tour
   (assets/mysubaru-kiosk-tour.html with its autoplay control
   protocol). window.OnboardingMap stays as-is: the case shell
   renders the diagnostics journey map beneath the Research tab
   and above the Ideation tab, and this file keeps the cp-1 /
   cp-2 / cp-3 anchors that map scrolls to.

   The deck's own interactive builds live in
   assets/subaru/embeds. Diagrams here are drawn natively
   rather than embedded as slide exports.
   ============================================================ */
(function () {
  const { useState, useRef, useEffect } = React;
  const PP = window.PPKit;
  const K = window.CSKit;
  const SectionHead = K.SectionHead;

  /* ============================================================
     Shared bits
     ============================================================ */

  function H3Block(props) {
    return (
      <div>
        <h3 className="pf-h3" style={{ margin: "0 0 10px", fontSize: "clamp(17px, 1.6vw, 21px)" }}>{props.title}</h3>
        {props.sub ? <p className="nmc-sub">{props.sub}</p> : null}
      </div>
    );
  }

  function Badge(props) {
    return <span className={"nmc-badge" + (props.val ? " val" : "") + (props.hyp ? " hyp" : "")}>{props.children}</span>;
  }

  function TitleRow(props) {
    return (
      <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
        <h3 className="pf-h3" style={{ margin: 0, fontSize: "clamp(17px, 1.6vw, 21px)" }}>{props.title}</h3>
        {props.badge ? <Badge val={props.val} hyp={props.hyp}>{props.badge}</Badge> : null}
      </div>
    );
  }

  function Chain(props) {
    return (
      <div className="nmc-chain">
        {props.nodes.map(function (n, i) {
          return (
            <React.Fragment key={i}>
              {i > 0 ? <span className="nmc-arr">&rarr;</span> : null}
              <div className={"nmc-node" + (n.cut ? " cut" : "")}>{n.t}{n.s ? <small>{n.s}</small> : null}</div>
            </React.Fragment>
          );
        })}
      </div>
    );
  }

  function MapBlock(props) {
    return (
      <div className="pf-glass nmc-map">
        {props.label ? <div className="pf-eyebrow" style={{ marginBottom: 14, color: "var(--accent)" }}>{props.label}</div> : null}
        <Chain nodes={props.nodes} />
        {props.note ? <div className="nmc-loop">{props.note}</div> : null}
      </div>
    );
  }

  /* A native diagram: framed, and always carrying a note that says what
     the reader is looking at. */
  function Dia(props) {
    return (
      <figure style={{ margin: 0, display: "flex", flexDirection: "column", gap: 12 }}>
        {props.label ? <div className="pf-eyebrow" style={{ color: "var(--label-tertiary)" }}>{props.label}</div> : null}
        <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(18px, 2vw, 30px)" }}>
          {props.children}
        </div>
        {props.caption ? <figcaption className="nmc-ev" style={{ borderTop: 0, paddingTop: 0, marginTop: 0 }}>{props.caption}</figcaption> : null}
      </figure>
    );
  }

  /* Containment drawn as containment: one tier physically inside another,
     with the actions that had no way to say which one they meant. */
  function NestDiagram(props) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
        <div style={{
          border: "1px solid var(--pf-border)", borderRadius: 14,
          padding: "clamp(16px, 1.8vw, 22px)", background: "var(--fill-tertiary)",
          display: "flex", flexDirection: "column", gap: 14,
        }}>
          <div>
            <div style={{ fontSize: 14.5, color: "var(--label-primary)" }}>{props.outer}</div>
            <div style={{ fontSize: 12, marginTop: 4, color: "var(--label-tertiary)" }}>{props.outerNote}</div>
          </div>
          <div style={{
            border: "1px dashed var(--pf-border)", borderRadius: 11,
            padding: "clamp(13px, 1.4vw, 18px)", background: "var(--pf-page-2, transparent)",
          }}>
            <div style={{ fontSize: 13.5, color: "var(--label-primary)" }}>{props.inner}</div>
            <div style={{ fontSize: 12, marginTop: 4, color: "var(--label-tertiary)" }}>{props.innerNote}</div>
          </div>
        </div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 8, alignItems: "center" }}>
          {props.actions.map(function (a) {
            return (
              <span key={a} style={{
                padding: "8px 14px", borderRadius: 8, fontSize: 12.5,
                border: "1px solid var(--pf-hairline)", color: "var(--label-secondary)",
              }}>{a}</span>
            );
          })}
          <span style={{ fontSize: 12.5, color: "var(--accent)", marginLeft: 4 }}>{props.ask}</span>
        </div>
      </div>
    );
  }

  /* Four wording options with their vote share and the reasons given. The
     reasons are the transferable part, so they are not collapsed away. */
  function VoteTable(props) {
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
        {props.rows.map(function (r) {
          return (
            <div key={r.t} className="pf-glass" style={{
              padding: "clamp(15px, 1.6vw, 20px)",
              display: "grid", gridTemplateColumns: "auto minmax(0, 1fr)", gap: "10px 18px", alignItems: "start",
              border: r.win ? "1px solid var(--accent)" : undefined,
            }}>
              <div style={{ textAlign: "right", minWidth: 54 }}>
                <div className="pf-num" style={{ fontSize: 24, fontWeight: 300, lineHeight: 1, color: r.win ? "var(--accent)" : "var(--label-tertiary)" }}>{r.v}%</div>
                <div style={{ fontSize: 10.5, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--label-tertiary)", marginTop: 5 }}>chose</div>
              </div>
              <div style={{ minWidth: 0, display: "flex", flexDirection: "column", gap: 7 }}>
                <div style={{ fontSize: 14, color: "var(--label-primary)" }}>{r.t}</div>
                <div style={{ fontSize: 13, lineHeight: 1.55, color: "var(--label-secondary)" }}>{r.w}</div>
                <div className="nmc-blk" style={{ margin: 0 }}><b>Liked</b>{r.liked}</div>
                <div className="nmc-blk" style={{ margin: 0 }}><b>Worried about</b>{r.worried}</div>
              </div>
            </div>
          );
        })}
      </div>
    );
  }

  /* Self-contained HTML prototype, auto-sized to its own content. */
  function Proto(props) {
    /* These deck exports unpack themselves after load and can replace
       their own body, so poll for a while and measure documentElement,
       which survives the swap. Height converges: the frame is sized to
       max(viewport, content), which on the next tick measures the same. */
    function fit(e) {
      var ifr = e.target;
      try {
        var doc = ifr.contentDocument;
        if (!doc) return;
        var go = function () {
          try {
            var d = ifr.contentDocument;
            if (!d) return;
            var hb = d.body ? d.body.scrollHeight : 0;
            var hd = d.documentElement ? d.documentElement.scrollHeight : 0;
            var h = Math.max(hb, hd);
            if (h) ifr.style.height = Math.ceil(h) + "px";
          } catch (err) {}
        };
        go();
        [300, 800, 1500, 2500, 4000].forEach(function (ms) { setTimeout(go, ms); });
        if (window.ResizeObserver && doc.documentElement) new ResizeObserver(go).observe(doc.documentElement);
      } catch (err) {}
    }
    return (
      <figure style={{ margin: 0, display: "flex", flexDirection: "column", gap: 14 }}>
        {props.intro ? <p className="nmc-sub">{props.intro}</p> : null}
        <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(14px, 1.4vw, 22px)" }}>
          <iframe title={props.title} src={props.src} loading="lazy" scrolling={props.scroll ? "auto" : "no"}
            onLoad={props.fixed ? undefined : fit}
            style={{ display: "block", width: "100%", height: props.h || 720, border: 0, borderRadius: 14, background: "#ffffff" }} />
        </div>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", gap: 16, flexWrap: "wrap" }}>
          {props.caption ? <figcaption className="nmc-ev" style={{ borderTop: 0, paddingTop: 0, marginTop: 0, flex: "1 1 360px" }}>{props.caption}</figcaption> : null}
          <a href={props.src} target="_blank" rel="noopener noreferrer" className="pf-btn gv-lift" style={{ textDecoration: "none", flex: "none" }}>
            Open full screen
            <i data-lucide="arrow-up-right" style={{ width: 15, height: 15, opacity: 0.8 }} />
          </a>
        </div>
      </figure>
    );
  }

  /* Phone-shaped prototype: fixed device geometry, scaled down to
     fit narrow columns instead of being cropped by them. */
  function PhoneProto(props) {
    const ref = useRef(null);
    const dw = props.dw || 410;
    const dh = props.dh || 872;
    function apply() {
      const ifr = ref.current;
      if (!ifr) return;
      try {
        const doc = ifr.contentDocument;
        if (!doc || !doc.body) return;
        const w = ifr.clientWidth || dw;
        const k = Math.min(1, w / dw);
        doc.body.style.zoom = String(k);
        ifr.style.height = Math.ceil(dh * k) + "px";
      } catch (e) {}
    }
    function onLoad() {
      const ifr = ref.current;
      try {
        if (props.mode && ifr && ifr.contentWindow && ifr.contentWindow.setMode) ifr.contentWindow.setMode(props.mode);
      } catch (e) {}
      apply(); setTimeout(apply, 220); setTimeout(apply, 900);
    }
    useEffect(function () {
      window.addEventListener("resize", apply);
      return function () { window.removeEventListener("resize", apply); };
    }, []);
    return (
      <figure style={{ margin: 0, display: "flex", flexDirection: "column", gap: 12 }}>
        {props.label ? <div className="pf-eyebrow" style={{ color: "var(--label-tertiary)" }}>{props.label}</div> : null}
        <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(12px, 1.2vw, 20px)" }}>
          <div style={{ maxWidth: dw, margin: "0 auto" }}>
            <iframe ref={ref} title={props.title} src={props.src} loading="lazy" scrolling="no" onLoad={onLoad}
              style={{ display: "block", width: "100%", height: dh, border: 0, borderRadius: 14, background: "#ffffff" }} />
          </div>
        </div>
        {props.caption ? <figcaption className="nmc-ev" style={{ borderTop: 0, paddingTop: 0, marginTop: 0 }}>{props.caption}</figcaption> : null}
      </figure>
    );
  }

  /* Metric row: label, figure, quiet bar. */
  function StatRow(props) {
    return (
      <div>
        <div className="nmc-stat"><span>{props.label}</span><b>{props.value}</b></div>
        <div className="nmc-bar" aria-hidden="true"><i style={{ width: props.fill || props.value }} /></div>
      </div>
    );
  }

  /* Question, Method, Result, Design consequence. */
  function QMRC(props) {
    return (
      <div style={{ display: "flex", flexDirection: "column" }}>
        <div className="nmc-blk"><b>Question</b>{props.q}</div>
        <div className="nmc-blk"><b>Method</b>{props.m}</div>
        <div className="nmc-blk dec"><b>Result</b>{props.r}</div>
        <div className="nmc-blk trade"><b>Design consequence</b>{props.c}</div>
      </div>
    );
  }

  function MetaCell(props) {
    return (
      <div className="pf-glass" style={{ gridColumn: "span 3", padding: "clamp(20px, 2vw, 28px)" }}>
        <div className="pf-eyebrow" style={{ marginBottom: 12 }}>{props.label}</div>
        <div className="pf-h3" style={{ fontSize: 17 }}>{props.value}</div>
      </div>
    );
  }

  /* ---------- data viz ported from subaru.jsx, same data ---------- */

  function BarChart(props) {
    const data = props.data, max = props.max || 80;
    const W = 820, H = 360, L = 40, R = 14, T = 16, B = 66;
    const pw = W - L - R, ph = H - T - B, n = data.length;
    const slot = pw / n, bw = Math.min(52, slot * 0.46);
    const y = function (v) { return T + ph - (v / max) * ph; };
    const grid = [0, 20, 40, 60, 80];
    return (
      <svg viewBox={"0 0 " + W + " " + H} width="100%" role="img" aria-label="Bar chart of reasons owners do not use the app" style={{ display: "block", overflow: "visible", maxWidth: 680, margin: "0 auto" }}>
        {grid.map(function (g) {
          return (
            <g key={g}>
              <line x1={L} x2={W - R} y1={y(g)} y2={y(g)} stroke="var(--pf-hairline)" strokeWidth="1" />
              <text x={L - 8} y={y(g) + 3} textAnchor="end" fontSize="9" fontWeight="300" fill="var(--label-tertiary)">{g}%</text>
            </g>
          );
        })}
        {data.map(function (d, i) {
          const cx = L + slot * i + slot / 2;
          const bh = (d.value / max) * ph;
          const words = d.label.split(" ");
          return (
            <g key={d.label}>
              <rect x={cx - bw / 2} y={y(d.value)} width={bw} height={bh} rx="6" fill="var(--accent)" opacity={i === 0 ? 0.7 : 0.5} />
              <text x={cx} y={y(d.value) - 7} textAnchor="middle" fontSize="9" fontWeight="300" fill="var(--label-secondary)">{d.value}%</text>
              <text x={cx} y={H - B + 18} textAnchor="middle" fontSize="9" fontWeight="300" fill="var(--label-tertiary)">
                {words.map(function (w, wi) { return <tspan key={wi} x={cx} dy={wi === 0 ? 0 : 12}>{w}</tspan>; })}
              </text>
            </g>
          );
        })}
      </svg>
    );
  }

  function Donut(props) {
    const pct = props.pct, r = 82, c = 2 * Math.PI * r, on = (pct / 100) * c;
    return (
      <svg viewBox="0 0 200 200" width="150" height="150" role="img" aria-label={pct + " percent"} style={{ display: "block" }}>
        <circle cx="100" cy="100" r={r} fill="none" stroke="var(--pf-hairline)" strokeWidth="12" />
        <circle cx="100" cy="100" r={r} fill="none" stroke="var(--accent)" strokeWidth="12" strokeLinecap="round"
          strokeDasharray={on + " " + (c - on)} strokeDashoffset={c * 0.25} transform="rotate(-90 100 100)" opacity="0.85" />
        <text x="100" y="110" textAnchor="middle" fontSize="30" fontWeight="300" fill="var(--accent)">{pct}%</text>
      </svg>
    );
  }

  /* ============================================================
     OPENING
     ============================================================ */

  const SIGNALS = [
    {
      k: "Signal 01", t: "Enrollment was spread across four surfaces, and every hand-off leaked",
      p: "To enroll, an owner moved across the head unit, a phone, and two web portals: download the app, sync with the head unit, confirm by email, and lean on retailer help at the counter. Each hand-off was a place to lose them, and none of the teams that owned those surfaces reported to the same person.",
    },
    {
      k: "Signal 02", t: "Leadership already tracked enrollment as a KPI",
      p: "Point-of-sale enrollment and initial enrollment were both reported upward. That meant onboarding work did not need to be sold as a design idea: it could be argued in the currency the business was already counting.",
    },
    {
      k: "Signal 03", t: "71% of owners were most open during vehicle purchase",
      p: "In our survey, 71% preferred to meet MySubaru at the moment they bought the car, then again when they downloaded the app. Waiting at the retailer, they have both the time and the attention to learn what they just bought.",
    },
    {
      k: "Signal 04", t: "The rebrand blurred what was being sold",
      p: "New tier names, reshuffled services, and an incremental pricing strategy created confusion inside and outside the company. People did not know what had changed, or what MySubaru now included.",
    },
  ];

  const CONDITIONS = [
    { k: "01", t: "Value clarity", p: "Owners have to understand the service before they can make a subscription decision. Nothing downstream can compensate for a product the buyer cannot describe." },
    { k: "02", t: "Point-of-sale ease", p: "The moment of vehicle purchase is one of the strongest opportunities to convert interest into enrollment, and it is the only moment where a person is standing beside the buyer." },
    { k: "03", t: "Cross-surface consistency", p: "Owners should be able to complete activation without being pushed between disconnected systems, especially not between a phone and a desktop browser." },
  ];

  function OpeningPanel(props) {
    const c = props.case;
    return (
      <div className="nmc cs-tab">
        <div style={{ maxWidth: 860 }}>
          <h2 className="pf-h2" style={{ margin: 0, fontSize: "clamp(21px, 2.2vw, 30px)" }}>{c.title}</h2>
          <p className="pf-lead" style={{ margin: "16px 0 0" }}>
            Turning subscription complexity into a clearer path from vehicle purchase to activation.
          </p>
          <p className="pf-body" style={{ margin: "18px 0 0", maxWidth: 800 }}>
            Getting owners to begin required more than simplifying sign-up. We had to make the service
            understandable, purchasable, and completable across a dealership, the web, and the mobile app.
          </p>
        </div>

        <div className="pf-bento" style={{ gridAutoRows: "auto" }}>
          <MetaCell label="Role" value={c.role} />
          <MetaCell label="Platform" value={c.platform} />
          <MetaCell label="Year" value={c.year} />
          <MetaCell label="Organization" value={c.org} />
        </div>
        <div style={{ display: "flex", flexWrap: "wrap", gap: 12 }}>
          {c.tags.map(function (t) { return <span key={t} className="pf-chip">{t}</span>; })}
        </div>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="The product, and what I owned inside it"
            sub="MySubaru connects the vehicle, its owner, and the Subaru brand across the ownership lifecycle. Before any of the design work, the problem had to be scoped honestly: what the service is, what I could actually decide, and what the business was paying for." />
          <div className="nmc-grid">
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">The product</div>
              <p>
                The service gives more than two million owners access to remote commands, vehicle status, safety
                and security support, service tools, trip experiences, and subscription management. When I joined
                the account, usage was heavily concentrated around a few remote commands: remote start, lock and
                unlock, and vehicle location, despite a much broader connected-service ecosystem.
              </p>
              <div className="nmc-ev">The opportunity was larger than improving individual features. My goal became to help MySubaru evolve from a remote control into a vehicle ownership companion.</div>
            </div>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">My role</div>
              <p>
                Senior Product Designer and design lead, working agency-side at Dentsu while embedded with Subaru
                of America. I owned product design across a system that involved mobile, web, retailer tools,
                vehicle interfaces, and multiple engineering teams: research, product strategy, information
                architecture, interaction design, visual systems, testing, retailer experience, and implementation.
              </p>
              <div className="nmc-ev">The people responsible for shipping the work did not report to me. Much of the role was creating evidence, frameworks, and shared decision-making tools strong enough to move teams without formal authority.</div>
            </div>
          </div>
        </section>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="The business model that constrained every decision"
            sub="MySubaru monetizes through connected-service subscriptions, and the advanced tier carries most of the value-driving functionality and most of the margin. I worked with strategy and data partners to connect experience decisions to one shared model." />
          <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(24px, 2.6vw, 40px)" }}>
            <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))" }}>
              <div>
                <div className="pf-eyebrow" style={{ marginBottom: 14, color: "var(--accent)" }}>Increases value</div>
                <K.ListBlock items={["Enrollment", "Sustained usage", "Value-feature adoption", "Returning users", "Subscription tier"]} />
              </div>
              <div>
                <div className="pf-eyebrow" style={{ marginBottom: 14 }}>Contributes cost</div>
                <K.ListBlock items={["Acquisition", "Infrastructure", "Authentication", "Messaging", "Vehicle-data refresh"]} />
              </div>
            </div>
            <p className="pf-body" style={{ margin: "26px 0 0", maxWidth: 760, color: "var(--label-primary)" }}>
              That model became an important constraint: a design improvement only mattered if it increased
              customer value without creating disproportionate operating cost. It is also why several obvious
              ideas, such as refreshing vehicle data more often, never made it past a first conversation.
            </p>
          </div>
        </section>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="Why onboarding was the highest-leverage place to work"
            sub="Enrollment is the bridge that carries a new owner from purchase to real value. Four signals pointed at it before I had drawn a single screen." />
          <div className="nmc-grid">
            {SIGNALS.map(function (s) {
              return (
                <div key={s.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{s.k}</div>
                  <h4>{s.t}</h4>
                  <p>{s.p}</p>
                </div>
              );
            })}
          </div>
          <div className="pf-glass nmc-card" style={{ marginTop: 4 }}>
            <div className="nmc-idx">What changed in the market</div>
            <h4>STARLINK became MySubaru</h4>
            <div style={{ display: "flex", flexWrap: "wrap", gap: "clamp(18px, 5vw, 64px)", alignItems: "center", marginTop: 14 }}>
              <div>
                <div className="pf-eyebrow" style={{ marginBottom: 12 }}>STARLINK</div>
                <K.ListBlock items={["Safety", "Security", "Concierge"]} />
              </div>
              <span aria-hidden="true" style={{ fontSize: 20, color: "var(--label-tertiary)" }}>&rarr;</span>
              <div>
                <div className="pf-eyebrow" style={{ marginBottom: 12, color: "var(--accent)" }}>MySubaru</div>
                <K.ListBlock items={["Companion", "Companion Plus"]} />
              </div>
            </div>
            <div className="nmc-ev">Following the rebrand, Companion Plus incorporated the features of Companion. That nesting is the detail that later turned a pricing problem into an entity-model problem.</div>
          </div>
        </section>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="The North Star"
            sub="Subaru Connected Service earns most of its profit from the advanced tier, so the goal was to move more owners into it, and to do that without inflating the cost side of the model." />
          <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(24px, 2.6vw, 40px)" }}>
            <p className="pf-h3" style={{ margin: 0, maxWidth: 820, fontSize: "clamp(16px, 1.5vw, 20px)", fontWeight: 300 }}>
              Reading the revenue composition, this case works three levers inside the profitability model:{" "}
              <span style={{ color: "var(--accent)" }}>attachment rate at point of sale</span>,{" "}
              <span style={{ color: "var(--accent)" }}>enrollment start rate</span>, and{" "}
              <span style={{ color: "var(--accent)" }}>enrollment completion</span>.
            </p>
            <p className="pf-body" style={{ margin: "18px 0 0", maxWidth: 760 }}>
              All three are set during onboarding. None of them are set by a single screen.
            </p>
          </div>
        </section>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="Three conditions the design had to satisfy"
            sub="When I mapped the connected-service journey, onboarding friction did not live in one screen. It accumulated: from understanding what Subaru was selling, to purchasing a subscription at the dealership, to activating the service across different devices. I reduced that to three conditions we needed to validate." />
          <div className="nmc-grid">
            {CONDITIONS.map(function (x) {
              return (
                <div key={x.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{x.k}</div>
                  <h4>{x.t}</h4>
                  <p>{x.p}</p>
                </div>
              );
            })}
          </div>
        </section>

        <section className="pf-glass pf-glass--thick" style={{ padding: "clamp(30px, 5vw, 60px)", textAlign: "center" }}>
          <div className="pf-eyebrow" style={{ marginBottom: 20 }}>The design question</div>
          <p className="pf-h2" style={{ margin: "0 auto", maxWidth: 900, fontSize: "clamp(18px, 2vw, 26px)", fontWeight: 300 }}>
            How might we reduce onboarding friction and increase subscription conversion through{" "}
            <span style={{ color: "var(--accent)" }}>clearer value</span>, a{" "}
            <span style={{ color: "var(--accent)" }}>stronger point-of-sale experience</span>, and a{" "}
            <span style={{ color: "var(--accent)" }}>consistent activation journey</span>?
          </p>
        </section>
      </div>
    );
  }

  /* ============================================================
     RESEARCH
     ============================================================ */

  const BARRIERS = [
    { label: "Unclear Value", value: 73 },
    { label: "Cost", value: 44 },
    { label: "Compatibility", value: 39 },
    { label: "Too Complicated", value: 29 },
    { label: "Awareness", value: 24 },
    { label: "Using Alternatives", value: 9 },
    { label: "Sign up barriers", value: 4 },
  ];

  const FRICTIONS = [
    { k: "Information friction", p: "I do not know this service or capability exists.", ev: "Reported as: awareness, too complicated." },
    { k: "Value friction", p: "I know it exists, but I am not convinced it is worth using or paying for.", ev: "Reported as: unclear value, cost, using alternatives." },
    { k: "Journey friction", p: "I intend to proceed, but usability or technical barriers prevent me from completing the action.", ev: "Reported as: sign-up barriers, compatibility." },
  ];

  const OWNER_STEPS = [
    "Owns a Subaru", "Created an account", "Knows Basic", "Started Basic",
    "Completed Basic", "Knows Advanced", "Started Advanced", "Completed Advanced",
  ];

  const OWNER_TYPES = [
    { k: "A", cleared: 7, stop: "Completed Advanced", type: "Journey friction", d: "Cleared every step up to the final confirmation in the advanced tier, then stopped. Someone who begins and does not finish has a journey problem, not a value problem: they already decided." },
    { k: "B", cleared: 6, stop: "Started Advanced", type: "Value friction", d: "Knew the advanced tier existed and never began enrolling in it. The tier was understood; the case for paying was not made." },
    { k: "C", cleared: 5, stop: "Knows Advanced", type: "Information friction", d: "Completed the basic tier and never learned the advanced tier existed. The largest missed revenue is here, and none of it is a persuasion problem yet." },
    { k: "D", cleared: 4, stop: "Completed Basic", type: "Journey friction", d: "Began enrollment in the basic tier and abandoned it. Failure at the very first enrollment step, before any paid decision is even reached." },
    { k: "E", cleared: 3, stop: "Started Basic", type: "Value friction", d: "Knew the basic tier and never started. Even a free trial has to be worth the setup effort, and this segment judged that it was not." },
    { k: "F", cleared: 2, stop: "Knows Basic", type: "Information friction", d: "Held a MySubaru account and never learned what the basic tier contained. Top-of-funnel information failure, inside a population that had already opted in once." },
    { k: "G", cleared: 0, stop: "Excluded", type: "Not addressable", d: "Not a vehicle owner. Excluded from the model, because a population that cannot enroll would distort the weighting of every priority beneath it." },
  ];

  function OwnerMatrix() {
    const [sel, setSel] = useState(2);
    const row = OWNER_TYPES[sel];
    return (
      <div className="nmc cs-tab">
        <div className="pf-glass nmc-map">
          <div style={{ minWidth: 660 }}>
            <div style={{ display: "grid", gridTemplateColumns: "104px repeat(8, 1fr)", gap: 6, alignItems: "end", marginBottom: 10 }}>
              <div style={{ fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--label-tertiary)" }}>Owner type</div>
              {OWNER_STEPS.map(function (s) {
                return <div key={s} style={{ fontSize: 10, lineHeight: 1.3, color: "var(--label-tertiary)", textAlign: "center" }}>{s}</div>;
              })}
            </div>
            {OWNER_TYPES.map(function (t, i) {
              const on = i === sel;
              return (
                <button key={t.k} onClick={function () { setSel(i); }} aria-pressed={on ? "true" : "false"}
                  style={{
                    width: "100%", display: "grid", gridTemplateColumns: "104px repeat(8, 1fr)", gap: 6,
                    alignItems: "center", padding: "9px 8px", marginBottom: 4, cursor: "pointer",
                    border: "1px solid " + (on ? "var(--accent)" : "transparent"), borderRadius: 10,
                    background: on ? "color-mix(in srgb, var(--accent) 8%, transparent)" : "transparent",
                    color: "inherit", font: "inherit", textAlign: "left",
                    transition: "background 240ms var(--glass-ease), border-color 240ms var(--glass-ease)",
                  }}>
                  <span style={{ fontSize: 12, color: on ? "var(--label-primary)" : "var(--label-secondary)" }}>
                    Type {t.k}{t.k === "G" ? " (excluded)" : ""}
                  </span>
                  {OWNER_STEPS.map(function (s, j) {
                    const cleared = j < t.cleared;
                    return (
                      <span key={s} aria-hidden="true" style={{
                        justifySelf: "center", width: 13, height: 13, borderRadius: "50%",
                        background: cleared ? "var(--accent)" : "var(--fill-secondary)",
                        border: "1px solid " + (cleared ? "transparent" : "var(--pf-border)"),
                        opacity: cleared ? (on ? 1 : 0.75) : 1,
                      }} />
                    );
                  })}
                </button>
              );
            })}
            <div style={{ display: "flex", gap: 18, marginTop: 12, fontSize: 11, color: "var(--label-tertiary)" }}>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
                <span aria-hidden="true" style={{ width: 11, height: 11, borderRadius: "50%", background: "var(--accent)" }} />Cleared
              </span>
              <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
                <span aria-hidden="true" style={{ width: 11, height: 11, borderRadius: "50%", background: "var(--fill-secondary)", border: "1px solid var(--pf-border)" }} />Stopped
              </span>
            </div>
          </div>
        </div>
        <div className="pf-glass nmc-card">
          <div className="nmc-idx">Type {row.k} : stops at {row.stop}</div>
          <h4>{row.type}</h4>
          <p>{row.d}</p>
        </div>
        <div className="nmc-hint">Select a row to read the friction it diagnoses.</div>
      </div>
    );
  }

  const CHECKPOINTS = [
    { k: "01", t: "Value clarity", p: "Customers and retailers needed a consistent understanding of what each subscription tier contained. Five teams could describe the same package in five ways." },
    { k: "02", t: "Point of sale", p: "The dealership needed a lower-friction way to demonstrate and sell connected services, without the retailer having to run the whole transaction by hand." },
    { k: "03", t: "Cross-surface activation", p: "Customers needed to finish account creation and activation without being forced out of mobile and back onto the web at the exact moment intent was highest." },
  ];

  function ResearchPanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Research" title="Analytics told us where owners stopped: not why"
          lead="Product analytics could locate the drop-offs precisely and explain none of them. At Subaru's Ambassador event I partnered with our senior researcher on intercept research and a focus group with highly engaged Subaru owners, then turned what came back into something the whole organization could use." />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="Seven reported symptoms became three types of friction"
            sub="The strongest finding was not price and it was not technical complexity. Among owners who were not using MySubaru, 75% did not know, understand, or recognize its value. That single number reframed the program: this was a comprehension problem before it was a conversion problem." />

          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))" }}>
            <div className="pf-glass" style={{ padding: "clamp(24px, 2.4vw, 36px)", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 20, textAlign: "center" }}>
              <Donut pct={75} />
              <p className="pf-body" style={{ margin: 0 }}>
                Among owners who do not use the app, 75% do not know, understand, or recognize its value.
              </p>
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 16, justifyContent: "center" }}>
              <K.Quote>
                I just don't find any value in it, to be honest. The only thing I liked was being able to locate
                the vehicle if it's stolen. And the remote start screen. None of those are enough to pay for.
              </K.Quote>
              <p className="pf-body" style={{ margin: 0 }}>
                Owners generally did not understand what they were paying for, if they were paying at all. The
                product was capable. The value was invisible.
              </p>
            </div>
          </div>

          <p className="nmc-sub" style={{ marginTop: 8 }}>
            The survey behind that finding asked non-users to name their reasons. Ranking them mattered less than
            noticing that the seven answers were not seven independent problems.
          </p>
          <div className="pf-glass" style={{ padding: "clamp(28px, 3.2vw, 48px) clamp(18px, 2vw, 32px)" }} data-om-raster="true">
            <div className="pf-eyebrow" style={{ marginBottom: 18 }}>Reasons cited by owners who do not use the app</div>
            <BarChart data={BARRIERS} max={80} />
          </div>
          <p className="nmc-sub">
            Read as a list, this is a backlog of seven unrelated fixes. Read as a diagnosis, it collapses into
            three kinds of breakdown, each of which calls for a completely different intervention.
          </p>

          <div className="nmc-grid">
            {FRICTIONS.map(function (f) {
              return (
                <div key={f.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{f.k}</div>
                  <p style={{ fontSize: 15, color: "var(--label-primary)" }}>{f.p}</p>
                  <div className="nmc-ev">{f.ev}</div>
                </div>
              );
            })}
          </div>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Why this outlived the study</div>
            <p>
              This became more than a research summary. It gave product, design, retail, and engineering a shared
              vocabulary for diagnosing where growth was breaking down, so a disagreement about a feature could be
              re-stated as a disagreement about which friction it was supposed to remove.
            </p>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="Behavior states showed which owners needed design intervention first"
            sub="Before designing solutions, I needed to know which owners represented the highest-value intervention. I mapped seven owner types across the connected-service journey: vehicle ownership, account creation, awareness of each subscription tier, enrollment start, and enrollment completion. The pattern of completion and abandonment reveals the likely friction on its own." />
          <OwnerMatrix />
          <p className="nmc-sub">
            The reading rule is simple and it is what made the matrix useful in a room: an owner who had never
            heard of the advanced tier has an information problem, someone who understood the tier but chose not
            to begin has a value problem, and someone who started enrollment but abandoned it has a journey problem.
          </p>

          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))" }}>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">The prioritization model</div>
              <h4>Three inputs, one deliberate guard</h4>
              <p>
                I combined the share of each owner segment, blocker severity, and a behavioral weight informed by
                the Theory of Planned Behavior. The weights were judgment, not measured causal coefficients, so I
                tested the ranking against multiple weighting combinations. The top priorities remained stable.
              </p>
              <div className="nmc-ev">A model whose ranking flips when you nudge a weight is not a prioritization tool, it is an argument wearing a spreadsheet.</div>
            </div>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">What it was actually for</div>
              <h4>A common object, not a decision machine</h4>
              <p>
                The model was never intended to make the decision for us. Its value was giving teams with
                different incentives something concrete to evaluate together, instead of relying on "I think
                users probably..." Retail, product, and engineering could argue about a weight, which is a
                far more productive argument than arguing about taste.
              </p>
              <div className="nmc-ev">This is also how the work moved at all: I had no authority over the teams that would build it.</div>
            </div>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="Three breakdowns defined the onboarding roadmap"
            sub="Mapping the friction across the ownership journey revealed three onboarding checkpoints. Each one belongs to a different surface and a different owner inside the organization, which is exactly why they had been treated as three unrelated problems." />
          <div className="nmc-grid">
            {CHECKPOINTS.map(function (x) {
              return (
                <div key={x.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{x.k}</div>
                  <h4>{x.t}</h4>
                  <p>{x.p}</p>
                </div>
              );
            })}
          </div>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Sequencing decision</div>
            <p>
              I deliberately addressed pricing clarity before point-of-sale design. The checkout experience could
              not explain a product that the organization itself described inconsistently, so building the
              transaction first would have shipped the confusion faster rather than removing it.
            </p>
          </div>
          <p className="nmc-sub">
            The journey map below traces the same enrollment path end to end, with the checkpoints marked where
            the friction actually lives. Selecting a checkpoint jumps to the design work it produced.
          </p>
        </section>
      </div>
    );
  }

  /* ============================================================
     IDEATION
     ============================================================ */

  const POS_PROGRESS = [
    ["QR code scanned", "The customer opened the link on their own phone. The retailer now knows the hand-off worked."],
    ["Checkout started", "The payment screen was reached. From here the customer is choosing, not being sold to."],
    ["Payment issue", "The payment could not be processed, with enough context for the retailer to help rather than restart."],
    ["Enrollment complete", "The subscription is active on the vehicle, and the retailer can move to vehicle hand-off."],
  ];

  const PILOT_STEPS = [
    ["Pilot in three dealerships", "Small enough to reverse, large enough to see variance between stores."],
    ["Success criteria agreed before launch", "Written down first, so the result cannot be reinterpreted afterwards."],
    ["In-flow and in-person feedback", "Behavior at the kiosk, plus what retail staff observe beside it."],
    ["Decide whether it scales", "Toward roughly 600 stores, only if the pilot earns it."],
  ];

  function IdeationPanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Ideation" title="Three checkpoints, designed as one system"
          lead="Each checkpoint targets one of the frictions from research, and each spans a surface owned by a different team: the retailer's administrative tools, the counter at point of sale, and the app in the customer's hand. Designing them separately was the failure mode I was trying to avoid." />

        <section id="cp-1" className="nmc" style={{ gap: 22, scrollMarginTop: 330 }}>
          <TitleRow title="Checkpoint 01 : the pricing problem was an entity-model problem" badge="PROPOSED" />
          <p className="nmc-sub">
            The first audience for pricing clarity was not the customer. It was Subaru itself. Following the
            rebrand, Companion Plus incorporated the features of Companion, while enrollment, upgrade, downgrade,
            cancellation, and refunds were distributed across different administrative flows. Five teams could
            describe the same package in different ways.
          </p>
          <Dia caption="The structure the retailer screen was describing, and the four actions it hung off it. Companion Plus literally contains Companion, and the interface inherited that containment as its interaction model: every action pointed at a row whose boundary was undefined. That is not a visual hierarchy problem. It is an entity-model problem, and no amount of typographic work would have fixed it.">
            <NestDiagram
              outer="MySubaru Companion Plus"
              outerNote="Five-year free trial, selected"
              inner="MySubaru Companion"
              innerNote="Contained by the tier above it"
              actions={["Upgrade", "Cancel", "Issue refund", "Modify"]}
              ask="Applied to which one?" />
          </Dia>
          <p className="nmc-sub" style={{ fontSize: 14.5 }}>
            The original retailer interface is live further on, in Iterations: working through it is the fastest
            way to feel why a visual fix would not have been enough.
          </p>
          <MapBlock label="What the original interface actually represented"
            nodes={[
              { t: "Billing account", s: "the real root" },
              { t: "Nested tier row", s: "Companion inside Companion Plus", cut: true },
              { t: "Action on a row", s: "cancel, upgrade, refund", cut: true },
              { t: "Ambiguous scope", s: "which subscription changed?", cut: true },
            ]}
            note="Every action inherited the ambiguity of the object it was attached to." />
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="Selectable subscription objects replaced the billing hierarchy" badge="PROPOSED" />
          <p className="nmc-sub">
            Instead of making the billing hierarchy easier to read, I proposed changing what the interface
            represented. Each tier became a selectable object with its own plan, price, term, status, and included
            services. Dependencies still existed, but the system enforced them rather than asking a retailer to
            remember them.
          </p>
          <MapBlock label="The revised model"
            nodes={[
              { t: "Subscription object", s: "plan, price, term, status" },
              { t: "Select or deselect", s: "one interaction" },
              { t: "System enforces dependency", s: "deselect Basic, Advanced follows" },
              { t: "Same model for every action", s: "enroll, upgrade, downgrade, cancel" },
            ]}
            note="Four administrative flows collapse into one interaction model, which is what made the pattern portable to the customer app." />
          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))" }}>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">Retailer</div>
              <h4>Execute a transaction efficiently</h4>
              <p>
                The retailer is mid-conversation with a customer and needs to change a subscription without
                second-guessing what a button will do. Status, term, and next bill are surfaced on the object
                itself so the state of the account is readable at a glance.
              </p>
            </div>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">Customer</div>
              <h4>Understand the difference well enough to decide</h4>
              <p>
                I carried the same object model into the customer experience but changed the information
                hierarchy around the customer's job. The customer-facing version adds progressive disclosure,
                included-service details, pricing, renewal information, and payment-term choices.
              </p>
            </div>
          </div>
          <div className="nmc-ev" style={{ borderTop: "1px dashed var(--pf-border)", paddingTop: 12 }}>
            One entity model, two information hierarchies. The evolution of both screens, and the live before and
            after of the retailer portal, are in Iterations.
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section id="cp-3" className="nmc" style={{ gap: 22, scrollMarginTop: 330 }}>
          <TitleRow title="Checkpoint 03 : activation should finish where it begins" badge="TESTED + SHIPPED" val />
          <p className="nmc-sub">
            Owners who enrolled at the dealership could download the MySubaru app, but account creation still
            pushed them onto the web. That hand-off introduced friction at exactly the moment when purchase
            intent was highest: standing in the showroom, phone already in hand.
          </p>
          <p className="nmc-sub">
            I added mobile activation and took ownership of the experience layer across eight authentication and
            account states already defined by engineering. Instead of one long form, the experience uses shorter
            sequential steps, clearer progress, and a direct path from dealership setup into an activated account.
          </p>
          <MapBlock label="The sequenced activation path"
            nodes={[
              { t: "One long form", s: "the original approach", cut: true },
              { t: "Welcome", s: "email validation" },
              { t: "Verification code" },
              { t: "Vehicle information", s: "VIN, with guidance" },
              { t: "Contact information" },
              { t: "Address" },
              { t: "Password" },
              { t: "Nickname and terms", s: "submit" },
            ]}
            note="The goal was simple: once a customer starts onboarding on their phone, they should not need another device to finish it." />
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section id="cp-2" className="nmc" style={{ gap: 22, scrollMarginTop: 330 }}>
          <TitleRow title="Checkpoint 02 : point of sale had to serve the buyer and the retailer" badge="PROPOSED" />
          <p className="nmc-sub">
            Research showed that 71% of owners were most open to learning about connected services during vehicle
            purchase. That gave us a high-value moment, but two distinct problems to solve inside it: the customer
            needs time and independence to understand the package, and the retailer needs visibility into whether
            the transaction is progressing successfully.
          </p>
          <p className="nmc-sub">
            I designed a contactless self-checkout flow in which the retailer generates a QR code and the customer
            explores the packages and completes payment on their own phone. Independence solves the customer's
            problem and creates the retailer's: a person who has handed the transaction away can no longer see it.
          </p>
          <div className="nmc-funnel">
            {POS_PROGRESS.map(function (f) {
              return <div key={f[0]} className="nmc-fstep"><div className="fn">{f[0]}</div><div className="fm">{f[1]}</div></div>;
            })}
          </div>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">The principle</div>
            <p>
              Failure states carry enough context for the retailer to assist without restarting the transaction.
              The retailer is not a bystander in this flow. They are the support layer, and the console is designed
              to tell them when to step in and when to stay out of the way.
            </p>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="A showroom interaction could demonstrate value before asking for commitment" badge="PILOT" val />
          <p className="nmc-sub">
            Checkout solved transaction friction, but it did not solve the deeper value problem the research had
            surfaced. A smoother way to buy something you do not understand is still a way to not buy it.
          </p>
          <p className="nmc-sub">
            I proposed an interactive showroom kiosk where customers could experience MySubaru before enrolling:
            trigger simulated remote commands, explore connected-service features, understand which capabilities
            belong to each tier, and see the value of the mobile experience in context. I designed the concept with
            our UI designers and copywriter using the redesign work running in parallel, so the showroom experience
            represented where the product was going rather than merely documenting the legacy app.
          </p>
          <div className="nmc-funnel">
            {PILOT_STEPS.map(function (f) {
              return <div key={f[0]} className="nmc-fstep"><div className="fn">{f[0]}</div><div className="fm">{f[1]}</div></div>;
            })}
          </div>
          <div className="nmc-ev" style={{ borderTop: "1px dashed var(--pf-border)", paddingTop: 12 }}>
            Instead of asking leadership to approve a national rollout immediately, I proposed a reversible first
            step. A pilot that can be stopped is far easier to approve than a rollout that cannot, and it produces
            the evidence the rollout decision actually needs.
          </div>
        </section>
      </div>
    );
  }

  /* ============================================================
     TESTING
     ============================================================ */

  function StepColumn(props) {
    return (
      <div style={{ flex: 1, minWidth: 0, border: "1px solid var(--pf-border)", borderRadius: 9, background: "var(--fill-secondary)", padding: "9px 10px", display: "flex", flexDirection: "column", gap: 5 }}>
        <div style={{ fontSize: 9, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--label-tertiary)" }}>{props.n}</div>
        <div style={{ fontSize: 11.5, color: "var(--label-primary)", lineHeight: 1.35 }}>{props.t}</div>
      </div>
    );
  }

  function FormCompare() {
    const LONG = ["Contact information", "Address information", "Set up password", "Nickname your vehicle", "Terms and submit"];
    const SHORT = ["Welcome", "Verification code", "Vehicle information", "Contact information", "Address", "Password", "Nickname and terms"];
    return (
      <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))" }}>
        <div className="pf-glass nmc-card">
          <div className="nmc-idx">Option A : one long form</div>
          <div style={{ border: "1px solid var(--pf-border)", borderRadius: 10, background: "var(--fill-secondary)", padding: "12px 13px", display: "flex", flexDirection: "column", gap: 7, marginTop: 4 }}>
            {LONG.map(function (l) {
              return <div key={l} style={{ fontSize: 11.5, color: "var(--label-secondary)", borderBottom: "1px dashed var(--pf-border)", paddingBottom: 6 }}>{l}</div>;
            })}
            <div style={{ alignSelf: "flex-start", fontSize: 10, borderRadius: 999, padding: "4px 12px", background: "var(--accent)", color: "#fff" }}>Submit</div>
          </div>
          <div className="nmc-ev">Everything visible at once, one commitment, no sense of progress.</div>
        </div>
        <div className="pf-glass nmc-card">
          <div className="nmc-idx">Option B : sequenced shorter steps</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 4 }}>
            {SHORT.map(function (s, i) {
              return <StepColumn key={s} n={"0" + (i + 1)} t={s} />;
            })}
          </div>
          <div className="nmc-ev">Each screen asks for one thing, with a progress bar carrying the sense of how much is left.</div>
        </div>
      </div>
    );
  }

  function TestingPanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Testing" title="Two questions I could not settle by argument"
          lead="Both of these were decisions where reasonable people disagreed and no amount of design taste was going to resolve it. In each case I converted the disagreement into something a study could answer, then let the answer bind me as much as anyone else." />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="Test 01 : shorter steps reduced perceived activation complexity" badge="TESTED + SHIPPED" val />
          <QMRC
            q="Would breaking account creation into shorter sequential steps make the activation journey easier to follow, or would it just make the same work feel longer?"
            m="Participants compared the longer-form approach with a sequenced account-creation experience that used clearer progress feedback, then chose between them."
            r="61.3% preferred the shorter-step structure."
            c="We moved forward with the sequenced mobile activation pattern, and our PMs translated the tested experience into implementation stories. The sequence became the structure of the eight-state activation flow in the Prototype chapter."
          />
          <p className="nmc-sub">
            The comparison itself was deliberately narrow: the same fields, the same validation rules, the same
            copy. Only the segmentation and the progress feedback changed, so a preference could only be about
            structure.
          </p>
          <FormCompare />
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Result</div>
            <div style={{ display: "grid", gap: 14, marginTop: 4, maxWidth: 460 }}>
              <StatRow label="Preferred the shorter-step format" value="61.3%" />
            </div>
            <div className="nmc-ev">Perceived ease is the thing that moves an activation funnel here, because the actual data collection was fixed by engineering and could not be reduced.</div>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="Test 02 : I turned an engineering disagreement into two falsifiable questions" badge="TESTED + SHIPPED" val />
          <p className="nmc-sub">
            A device without a passcode cannot safely support biometric login or stay-signed-in behavior.
            Engineering's proposed solution was technically correct: label the phone an "unsecured device" and
            hide the unavailable features.
          </p>
          <p className="nmc-sub">
            I disagreed for two reasons. The message described a technical state without giving the owner a path
            forward. And hiding Face ID removed any opportunity for users to discover that the capability existed
            at all, which quietly costs a security feature its adoption.
          </p>
          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(300px, 1fr))" }}>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">Question 01</div>
              <h4>What language helps users understand what to do next?</h4>
              <p>I worked with our copywriter on four messaging alternatives, ranging from the original technical wording to an explanation that connected the required action to the benefit it unlocks.</p>
            </div>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">Question 02</div>
              <h4>Should unavailable capabilities disappear, or remain visible with an explanation?</h4>
              <p>Two interaction treatments: hide the feature entirely, or keep it visible and explain the condition when the user reaches for it.</p>
            </div>
          </div>
          <Dia caption="Testing the wording alongside the reasons participants gave for it mattered more than the winner: option 3 lost on length, not on accuracy, and option 4 lost on the words missing and unsecure making people nervous. That is transferable guidance for the next warning message, not just this one.">
            <VoteTable rows={[
              {
                v: 0, t: "“Unsecured device”",
                w: "The original engineering wording. Technically accurate.",
                liked: "Nothing. No participant chose it.",
                worried: "It names a state without naming an action, so there is nothing to do about it.",
              },
              {
                v: 60, t: "Set up a passcode to use Face ID", win: true,
                w: "Connects the required action to the capability it unlocks, and says where to do it.",
                liked: "It explains what to do and why, and the benefit is concrete.",
                worried: "Slightly longer than the alternatives.",
              },
              {
                v: 20, t: "The long explanatory version",
                w: "The same reasoning at greater length, with more of the security rationale spelled out.",
                liked: "Most complete account of why the requirement exists.",
                worried: "Too long to read at a login screen. It lost on length, not on accuracy.",
              },
              {
                v: 20, t: "The short warning version",
                w: "Compact phrasing that kept the words missing and unsecure.",
                liked: "Brief.",
                worried: "Missing and unsecure made participants nervous about their own device.",
              },
            ]} />
          </Dia>
          <Dia caption="The two interaction treatments, and what each one does with a capability the device cannot currently support.">
            <PP.OrderFlip labels={["Option 01: explain it permanently", "Option 02: explain it on reach"]}
              before={[
                "A persistent banner sits above the login form",
                "The condition is stated whether or not it is relevant right now",
                "Face ID is not shown as a control",
                "Nothing to reach for, so nothing to discover",
              ]}
              after={[
                "The Face ID control stays visible in the login form",
                "Reaching for it opens the explanation, at the moment it is relevant",
                "The explanation links directly into device settings",
                "The capability stays discoverable even while it is unavailable",
              ]} />
          </Dia>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Results</div>
            <div style={{ display: "grid", gap: 16, marginTop: 4, maxWidth: 520 }}>
              <StatRow label="Chose the original 'unsecured device' wording" value="0%" fill="0%" />
              <StatRow label="Preferred the explanation that connected action to benefit" value="60%" />
              <StatRow label="Preferred keeping unavailable functionality visible" value="80%" />
            </div>
            <div className="nmc-ev">The winning message set up a passcode to use Face ID, said why, and gave per-platform instructions for where to do it.</div>
          </div>
          <div className="pf-glass pf-glass--thick nmc-card">
            <div className="nmc-idx">Design consequence</div>
            <p style={{ fontSize: 15, color: "var(--label-primary)" }}>
              We shipped the tested version. The important part of this decision was not winning an argument
              through stronger design taste. It was making my opinion falsifiable and giving engineering and
              product evidence they could evaluate with me: if 60% had chosen their wording, we would have
              shipped theirs.
            </p>
          </div>
        </section>
      </div>
    );
  }

  /* ============================================================
     ITERATIONS
     ============================================================ */

  const OBJECT_RULES = [
    {
      k: "Rule 1", t: "The interface represents subscriptions, not billing rows",
      p: "The original screen was a faithful view of the billing system, which is precisely what made it unusable. I redrew the unit of the interface as the thing the retailer and the customer both talk about: a subscription, with a plan, a price, a term, a status, and a set of included services.",
      ev: "Faithfulness to a backend schema is not neutrality. It is a design decision that hands the system's complexity to the user.",
    },
    {
      k: "Rule 2", t: "Dependencies are enforced by the system, not remembered by the user",
      p: "Companion Plus depends on Companion. In the original portal that dependency lived in retailer training and in tribal knowledge, which is why cancel and upgrade were ambiguous. In the object model the dependency is expressed as behavior: deselecting the basic tier deselects the advanced tier with it, visibly.",
      ev: "The rule did not disappear. It moved from the retailer's memory into the interface, where it can be seen and undone.",
    },
    {
      k: "Rule 3", t: "One interaction model covers four administrative flows",
      p: "Enrollment, upgrade, downgrade, and cancellation had each grown their own flow. Once a tier is a selectable object, all four are the same gesture applied to a different object, which is what made the pattern portable into the customer app without a second design system.",
      ev: "Fewer flows also meant fewer places for the five internal descriptions of a package to diverge again.",
    },
  ];

  const QUESTIONS = [
    {
      k: "01 : sequencing", t: "Should pricing clarity or point-of-sale design come first?",
      q: "Point-of-sale work was the visible, executive-facing part of the program, and it was the easier thing to start.",
      d: "Pricing clarity first, inside the retailer's own tools, before any checkout design.",
      tr: "The visible work landed later, and I spent weeks on an internal administrative surface that no customer would ever see. I accepted that, because a checkout experience cannot explain a product the organization describes five different ways: shipping it first would only have distributed the confusion faster.",
    },
    {
      k: "02 : representation", t: "Make the hierarchy readable, or change what the interface represents?",
      q: "The cheap fix was a visual one: better grouping, clearer labels, an explanatory tooltip on cancel.",
      d: "Change the entity the interface represents. Each tier becomes a selectable subscription object.",
      tr: "A far bigger change to argue for, touching billing integration rather than a stylesheet, and it required engineering to enforce dependencies that had previously been the retailer's problem. In exchange, the ambiguity is removed rather than annotated.",
    },
    {
      k: "03 : two audiences", t: "Should the retailer and the customer see the same subscription screen?",
      q: "One screen would be cheaper to build and would guarantee that both sides described a plan identically.",
      d: "One entity model, two information hierarchies. The retailer view optimizes for executing a transaction; the customer view adds progressive disclosure, included-service detail, renewal information, and payment-term choices.",
      tr: "Two surfaces to maintain and to keep in step. A single shared screen would have made one of the two jobs measurably worse, and the retailer's job is performed in front of a waiting customer.",
    },
    {
      k: "04 : ownership", t: "How far into the authentication system should the design reach?",
      q: "Engineering had already defined eight authentication and account states, and redefining them would have restarted a system conversation that was closed.",
      d: "Take ownership of the experience layer over the existing states rather than the state machine itself: sequencing, progress, wording, and the route from dealership setup into an activated account.",
      tr: "I could not remove a state I thought was redundant. What I could do was make each one legible and short, which is what the 61.3% preference result was actually measuring.",
    },
    {
      k: "05 : rollout", t: "Ask for a national kiosk rollout, or a reversible first step?",
      q: "The kiosk demonstrated well, and there was appetite to talk about scale immediately.",
      d: "A pilot in three dealerships, with success criteria agreed before launch and both in-flow and in-person feedback collected.",
      tr: "A slower path to Subaru's roughly 600-store retail network, and the risk that momentum fades between pilot and decision. In exchange the downside is capped, and the scaling decision gets made on evidence rather than on the strength of the demo.",
    },
  ];

  function IterationsPanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Iterations" title="From a billing hierarchy to a system of subscription objects"
          lead="The retailer's administration portal is where the pricing confusion became operational: the place where a person had to act on a structure nobody could describe consistently. Both versions below are live. Working through the original is the fastest way to feel why a visual fix would not have been enough." />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="The original, as retailers actually used it"
            sub="Read the subscription panel first. A single nested Basic plan carries four separate actions: upgrade, cancel, issue refund, modify. None of them state what they apply to, because the object they apply to has no boundary on screen." />
          <Proto title="MySubaru retailer administration portal, original subscription management"
            src="assets/subaru/embeds/subscription-before.html" h={760}
            caption="What breaks here is not legibility, it is scope. Because Companion Plus contains Companion, cancel could plausibly mean cancel the advanced capabilities, cancel this tier, or cancel the customer's entire subscription. Retailers resolved that ambiguity by calling support, which is a cost line in the same business model the program was trying to improve." />
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="Three rules I applied to the redesign"
            sub="Each rule came from a specific failure in the screen above, and each one had to survive contact with the billing system rather than pretending it did not exist." />
          <div className="nmc-grid">
            {OBJECT_RULES.map(function (r) {
              return (
                <div key={r.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{r.k}</div>
                  <h4>{r.t}</h4>
                  <p>{r.p}</p>
                  <div className="nmc-ev">{r.ev}</div>
                </div>
              );
            })}
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="The same object model, re-hierarchized for two different jobs"
            sub="Retailers need to execute a transaction efficiently. Customers need to understand the difference between plans well enough to decide. The objects are identical; what changes is what each audience sees first." />
          <Dia caption="One entity model, two reading orders. The retailer's first line is account state, because their job is to execute a transaction correctly. The customer's first line is the choice, because their job is to decide. Nothing about the objects changes between the two.">
            <PP.OrderFlip labels={["Retailer: transaction first", "Customer: decision first"]}
              before={[
                "Tier, and its current status",
                "Term: start date, expiry, days remaining",
                "Next bill",
                "Actions, scoped to the selected object",
                "The dependency stated plainly: deselect Basic and Advanced follows",
              ]}
              after={[
                "Tier, and whether they have it",
                "Plan and payment term, as a visible choice",
                "Price for each term, side by side",
                "Included services, expanding in place for comparison",
                "One confirm, at the end",
              ]} />
          </Dia>
          <div className="nmc-ev" style={{ borderTop: "1px dashed var(--pf-border)", paddingTop: 12 }}>
            Because both surfaces derive from one entity model, a change to what a tier contains updates a
            definition rather than two independently maintained descriptions. That was the actual argument for
            doing it this way, and it is the argument that moved engineering.
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <H3Block title="Five decisions, and what each one cost"
            sub="These are the choices where the alternative was genuinely defensible. Recording the trade-off alongside the decision is what let other teams disagree with the price rather than with me." />
          <div className="nmc-qgrid">
            {QUESTIONS.map(function (r) {
              return (
                <div key={r.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{r.k}</div>
                  <h4>{r.t}</h4>
                  <div className="nmc-blk"><b>Question</b>{r.q}</div>
                  <div className="nmc-blk dec"><b>Decision</b>{r.d}</div>
                  <div className="nmc-blk trade"><b>Trade-off</b>{r.tr}</div>
                </div>
              );
            })}
          </div>
        </section>
      </div>
    );
  }

  /* ============================================================
     PROTOTYPE
     ============================================================ */

  function KioskFrame() {
    const frameRef = useRef(null);
    const [playing, setPlaying] = useState(true);
    const [loaded, setLoaded] = useState(false);

    function post(action) {
      const ifr = frameRef.current;
      if (ifr && ifr.contentWindow) {
        try { ifr.contentWindow.postMessage({ source: "kiosk-ctrl", action: action }, "*"); } catch (e) {}
      }
    }
    useEffect(function () {
      var reduced = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
      if (reduced) { post("autoplay-off"); return; }
      post(playing ? "autoplay-on" : "autoplay-off");
    }, [playing, loaded]);

    return (
      <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(14px, 1.6vw, 26px)" }}>
        <div style={{ position: "relative", width: "100%", aspectRatio: "16 / 9", borderRadius: 16, overflow: "hidden", background: "#0B1F3A" }}>
          <iframe ref={frameRef} title="MySubaru showroom kiosk tour" src="assets/mysubaru-kiosk-tour.html"
            onLoad={function () { setLoaded(true); }}
            style={{ position: "absolute", inset: -1, width: "calc(100% + 2px)", height: "calc(100% + 2px)", border: 0, background: "#0B1F3A" }} />
        </div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 16, marginTop: 18 }}>
          <button onClick={function () { setPlaying(!playing); }} className="pf-btn gv-lift" aria-label={playing ? "Pause tour" : "Play tour"}>
            <i data-lucide={playing ? "pause" : "play"} style={{ width: 16, height: 16, opacity: 0.85 }} />
            {playing ? "Pause tour" : "Play tour"}
          </button>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <button onClick={function () { setPlaying(false); post("back"); }} className="gv-lift" aria-label="Previous screen"
              style={{ width: 44, height: 44, borderRadius: "50%", border: "1px solid var(--pf-border)", background: "var(--pf-glass-tint)", cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center", color: "var(--label-primary)" }}>
              <i data-lucide="chevron-left" style={{ width: 18, height: 18 }} />
            </button>
            <button onClick={function () { setPlaying(false); post("next"); }} className="gv-lift" aria-label="Next screen"
              style={{ width: 44, height: 44, borderRadius: "50%", border: "1px solid var(--pf-border)", background: "var(--pf-glass-tint)", cursor: "pointer", display: "inline-flex", alignItems: "center", justifyContent: "center", color: "var(--label-primary)" }}>
              <i data-lucide="chevron-right" style={{ width: 18, height: 18 }} />
            </button>
          </div>
          <span className="pf-body" style={{ margin: 0, fontSize: 13, color: "var(--label-tertiary)" }}>In-store kiosk, retailer waiting area</span>
        </div>
      </div>
    );
  }

  function PrototypePanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Prototype" title="Four working pieces of the onboarding system"
          lead="Each one is the artifact at the end of a checkpoint: the model that makes the product describable, the flow that lets activation finish on the phone it started on, the transaction that splits cleanly between a customer and a retailer, and the showroom experience that gives a buyer something to try before being asked to commit. Status labels are the honest ones." />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="01 : Subscription management, retailer and customer" badge="PROPOSED" />
          <Proto title="MySubaru retailer subscription manager, redesigned"
            src="assets/subaru/embeds/subscription-manager.html" h={780}
            intro="Try the subscription model. Click a plan card to select or deselect it, and watch what the interface claims about scope. The redesign converts a nested billing hierarchy into a consistent selection model, with plan, term, status, and included services exposed on the object itself."
            caption="The underlying dependency logic still exists, but it is enforced by the system rather than exposed as a rule the user has to remember. Enrollment, upgrade, downgrade, and cancellation all become the same gesture applied to a different object." />
          <p className="nmc-sub">
            The customer end of the same model, before and after, both live. Each one walks its own subscription
            screen; hover either to take over. The two builds are what the pricing-clarity argument looks like from
            the side of the person being asked to pay.
          </p>
          <PP.Row compare>
            <PP.Phone src="phone-fh.html" demo="s15-old" badge="Before: the old subscription page"
              title="The customer subscription page as it was"
              note="Capabilities as a list of toggles. A customer can switch things on and off without ever learning which plan they are on, what it contains, or what changing it costs." />
            <PP.Phone src="phone.html" demo="s15-new" badge="After: plan selection"
              title="The redesigned customer plan selection"
              note="The same objects with the hierarchy rebuilt around a decision: tier status, then plan and payment term as a visible choice, then included services on demand. Watch the dependency enforce itself when Companion is selected." />
          </PP.Row>
          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))" }}>
            <div className="pf-glass nmc-card">
              <div className="nmc-idx">Prototype boundaries</div>
              <p>
                The portal prototype is a faithful interactive rebuild of the redesigned screens, not production
                software: plan data is fixed sample data for one account, and the retailer actions confirm rather
                than call a billing service. The selection behavior and the dependency enforcement, which are the
                parts under evaluation, are real.
              </p>
              <div className="nmc-ev">Status: proposed. This work reached design and interactive prototype, not a released retailer build.</div>
            </div>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="02 : Mobile account activation" badge="TESTED + SHIPPED" val />
          <p className="nmc-sub">
            Complete onboarding without leaving mobile. This flow closes the gap between dealership enrollment and
            account activation by letting customers create and link their account directly inside MySubaru,
            instead of being emailed to a desktop browser at the moment their intent is highest.
          </p>
          <Dia caption="The tested comparison. Each screen in the sequence asks for one thing, carries a progress bar, and includes the guidance that used to live in a support call: what a VIN is and where to find it on the vehicle. Increasing perceived ease is what the 61.3% preference was measuring: the same fields, in a shape that tells you how much is left.">
            <PP.OrderFlip labels={["One long form", "Seven sequential screens"]}
              before={[
                "Every field on one screen, length visible up front",
                "No indication of how far along you are",
                "VIN asked for with no explanation of where to find it",
                "One submit, and any error sends you back into the whole form",
              ]}
              after={[
                "Welcome, and what the next few steps will ask for",
                "Verification code",
                "Vehicle information, with VIN guidance in place",
                "Contact information",
                "Address",
                "Password",
                "Vehicle nickname",
              ]} />
          </Dia>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Scope of the status label</div>
            <p>
              The sequenced structure was tested and translated into implementation stories by our PMs, and the
              passcode and Face ID messaging inside this flow shipped in the tested wording. I owned the
              experience layer across the eight authentication and account states; the states themselves were
              defined by engineering before I joined the flow.
            </p>
          </div>
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="03 : Contactless point-of-sale checkout" badge="PROPOSED" />
          <p className="nmc-sub">
            One transaction, two coordinated experiences. The customer can explore and pay independently on their
            own phone while the retailer sees enough progress to intervene when support is actually needed. Both
            sides are live below, and they are designed to be read together: the console exists because the phone
            takes the transaction out of the retailer's hands.
          </p>
          <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))", alignItems: "start" }}>
            <PhoneProto title="MySubaru contactless self-checkout, customer phone"
              src="assets/subaru/embeds/checkout.html" dw={410} dh={872}
              label="Customer side : their own phone, after scanning the QR code" />
            <div style={{ display: "flex", flexDirection: "column", gap: 16, alignSelf: "start" }}>
              <div className="pf-glass nmc-card" style={{ height: "auto" }}>
                <div className="nmc-idx">Why the phone, not the counter tablet</div>
                <p>
                  Research put 71% of owners at their most receptive during vehicle purchase, but receptive is not
                  the same as unhurried. Handing the transaction to the customer's own device gives them the one
                  thing a shared counter screen cannot: time to read without a person waiting on the other side of
                  it.
                </p>
                <div className="nmc-ev">The retailer generates the QR code, so the hand-off is deliberate rather than a link sent into the void.</div>
              </div>
              <div className="pf-glass nmc-card" style={{ height: "auto" }}>
                <div className="nmc-idx">What the customer is looking at</div>
                <p>
                  The customer reviews all three plans at their own pace, expanding and collapsing what each one
                  includes, and confirms payment without a retailer reading the plan sheet aloud to them. This is
                  the same tier content as the app, on the surface where the purchase decision is actually being
                  made.
                </p>
              </div>
            </div>
          </div>
          <Proto title="MySubaru retailer checkout console"
            src="assets/subaru/embeds/portal/index.html" h={800} fixed scroll
            intro="The retailer side of the same transaction. The console generates the QR code, then reports the customer's progress live: QR scanned, checkout started, payment issue, enrollment completed."
            caption="The failure state is the part that matters. Payment could not be processed is reported with the time it happened, a retry that resumes the customer's session rather than restarting it, and three concrete things the retailer can check. The retailer is not a bystander in this flow: they are the support layer, and the console tells them when to step in." />
        </section>

        <hr className="pf-rule" style={{ margin: 0 }} />

        <section className="nmc" style={{ gap: 22 }}>
          <TitleRow title="04 : Interactive showroom experience" badge="PILOT" val />
          <p className="nmc-sub">
            Demonstrating value before enrollment. The kiosk lets a prospective connected-service customer explore
            real MySubaru behaviors in the showroom instead of relying on a verbal sales explanation: trigger
            simulated remote commands, see which capabilities belong to which tier, and watch the app respond
            while their vehicle is being prepared.
          </p>
          <KioskFrame />
          <p className="nmc-sub" style={{ fontSize: 13.5, color: "var(--label-tertiary)" }}>
            The tour advances on its own so the screen is never dead in a showroom, and the board stays fully
            interactive if a customer takes over. The app screens it shows come from the redesign running in
            parallel, so the demonstration represents where the product was going rather than documenting the
            legacy app.
          </p>
          <div className="pf-glass nmc-card">
            <div className="nmc-idx">Status : pilot, not a launch</div>
            <p>
              Three dealerships, with success criteria agreed before launch and both in-flow and in-person
              feedback collected. Those results determine whether the concept scales toward Subaru's roughly
              600-store retail network. Nothing here was rolled out nationally, and the pilot was scoped
              specifically so that a negative result would be cheap.
            </p>
          </div>
        </section>
      </div>
    );
  }

  /* ============================================================
     OUTCOME
     ============================================================ */

  const CONTRIBUTIONS = [
    { k: "Value clarity", t: "Pricing clarity made the product easier to explain", p: "One entity model gave retailers, support, and the app the same description of what a tier contains, which removed the ambiguity that had been resolved by phone calls and guesswork." },
    { k: "Point of sale", t: "Point-of-sale design reduced transaction friction", p: "Contactless self-checkout let the customer read and decide at their own pace, while the retailer console kept the transaction visible enough to rescue when payment failed." },
    { k: "Activation", t: "Mobile activation removed a structural break", p: "Account creation stopped pushing owners from a phone in the showroom onto a desktop browser at home, which was a break in the journey rather than a usability annoyance." },
  ];

  function OutcomePanel() {
    return (
      <div className="nmc cs-tab">
        <SectionHead kicker="Outcome" title="A clearer path into the value-generating tier"
          lead="The onboarding work connected three previously fragmented problems: what Subaru was selling, how retailers helped customers buy it, and how owners completed activation afterward. They had been three teams' problems. Treating them as one system is what made the numbers below possible to move at all." />

        <div className="nmc-grid" style={{ gridTemplateColumns: "repeat(auto-fit, minmax(280px, 1fr))" }}>
          <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(26px, 3vw, 44px)", display: "flex", flexDirection: "column", justifyContent: "center" }}>
            <div className="pf-num" style={{ fontSize: "clamp(28px, 3vw, 40px)", fontWeight: 300, lineHeight: 1, color: "var(--accent)" }}>96%</div>
            <p className="pf-h3" style={{ margin: "20px 0 0", fontSize: "clamp(16px, 1.4vw, 19px)", fontWeight: 300 }}>All-level MySubaru enrollment.</p>
          </div>
          <div className="pf-glass pf-glass--thick" style={{ padding: "clamp(26px, 3vw, 44px)", display: "flex", flexDirection: "column", justifyContent: "center" }}>
            <div className="pf-num" style={{ fontSize: "clamp(28px, 3vw, 40px)", fontWeight: 300, lineHeight: 1, color: "var(--accent)" }}>52.9%</div>
            <p className="pf-h3" style={{ margin: "20px 0 0", fontSize: "clamp(16px, 1.4vw, 19px)", fontWeight: 300 }}>Adoption of the paid, value-generating tier.</p>
          </div>
        </div>

        <section className="nmc" style={{ gap: 20 }}>
          <H3Block title="What each piece contributed"
            sub="Together, these efforts contributed to an environment in which all-level enrollment reached 96% and adoption of the paid, value-generating tier reached 52.9%." />
          <div className="nmc-grid">
            {CONTRIBUTIONS.map(function (x) {
              return (
                <div key={x.k} className="pf-glass nmc-card">
                  <div className="nmc-idx">{x.k}</div>
                  <h4>{x.t}</h4>
                  <p>{x.p}</p>
                </div>
              );
            })}
          </div>
        </section>

        <section className="pf-glass nmc-card">
          <div className="nmc-idx">How to read these numbers</div>
          <p style={{ fontSize: 14.5 }}>
            These are business outcomes associated with the broader onboarding and activation program, measured
            across a staged rollout rather than a controlled holdout. The onboarding work shipped alongside other
            product, retail, and marketing changes, so the honest claim is contribution to an environment, not
            causation by any single interface. Where a specific design decision does have a controlled result
            behind it, such as the 61.3% and 60% preference findings, that result is reported in Testing with its
            method attached.
          </p>
        </section>

        <section className="pf-glass pf-glass--thick" style={{ padding: "clamp(24px, 2.6vw, 40px)", borderLeft: "2px solid var(--accent)" }}>
          <div className="nmc-idx">What came next</div>
          <p className="pf-h3" style={{ margin: 0, maxWidth: 780, fontSize: "clamp(16px, 1.5vw, 20px)", fontWeight: 300 }}>
            Onboarding solved the first growth problem: helping owners understand the service, enroll, and
            activate it. The next question was harder: what would make them come back when they did not need a
            remote command?
          </p>
          <p className="pf-body" style={{ margin: "16px 0 0", maxWidth: 720 }}>
            That question became the MySubaru Experience Redesign, the retention half of the same program.
          </p>
        </section>
      </div>
    );
  }

  /* ---------- register ---------- */
  window.CASE_PANELS = window.CASE_PANELS || {};
  const reg = window.CASE_PANELS["mysubaru-onboarding"] = window.CASE_PANELS["mysubaru-onboarding"] || {};

  reg.Opening = OpeningPanel;
  reg.Research = ResearchPanel;
  reg.Ideation = IdeationPanel;
  reg.Testing = TestingPanel;
  reg.Iterations = IterationsPanel;
  reg.Prototype = PrototypePanel;
  reg.Outcome = OutcomePanel;
})();
