  :root{
    /* ---- I 4 Invent brand ----
       Every colour on this page comes from the logo: a lightbulb drawn as a
       network, running yellow → lime → green → teal → blue, standing on a navy
       screw base. The wordmark is that lime filled inside a navy outline, so
       lime is the highlight and navy is the structure — never the other way
       round. Lime scores ~2:1 on white, so it does the DECORATIVE work (bars,
       rules, glows, fills) and --brand-lime-ink does anything that must be read. */
    --brand-yellow:#F2E70B;
    --brand-lime:#B5D334;
    --brand-lime-mid:#A9C822;
    --brand-lime-ink:#54700B;
    --brand-lime-dark:#40560A;
    --brand-lime-soft:#F0F7D8;
    --brand-green:#5CB85C;
    --brand-teal:#22B08A;
    --brand-cyan:#12B0B5;
    --brand-blue:#0092B8;
    --brand-navy:#0F2C4E;

    --paper:#EDF1F4;
    --panel:#F6F9FB;
    --panel-2:#ffffff;
    --canvas:#FAFCFD;
    --ink:#0F2C4E;
    --ink-soft:#4A6480;
    /* "faint" is a rank in the hierarchy, not a licence to be unreadable: the
       old grey scored 2.5:1 on white and it carries card meta and KPI labels */
    --ink-faint:#5C7189;
    --line:#CFDBE4;
    --line-soft:#E3EBF1;
    /* the accent tokens kept their old names so every rule that already reads
       them recolours at once; they point at the accent cyan now, not copper */
    --accent:#0097B2;
    --accent-deep:#00697F;
    --accent-dark:#00505F;
    --accent-soft:#E1F3F8;
    --copper:var(--accent);
    --copper-deep:var(--accent-deep);
    --copper-soft:var(--accent-soft);
    --pin:#12B0B5;
    --pin-soft:rgba(18,176,181,.18);
    --live:#22B08A;
    --live-deep:#0F6B58;
    --danger:#C8443F;
    --shadow:0 2px 10px rgba(15,44,78,.11);
    /* overlays float above the page, so their shadow carries the accent tint */
    --shadow-pop-sm:0 6px 22px rgba(0,105,127,.20), 0 1px 4px rgba(15,44,78,.10);
    --shadow-pop:0 10px 34px rgba(0,105,127,.26), 0 2px 8px rgba(15,44,78,.12);
    --shadow-pop-lg:0 18px 50px rgba(0,105,127,.34), 0 3px 12px rgba(15,44,78,.16);
    --font-ui:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
    --font-display:'Chakra Petch','IBM Plex Sans',system-ui,sans-serif;
    --font-mono:'IBM Plex Mono',ui-monospace,'Cascadia Mono',Consolas,monospace;
    --rp:0px;
  }
  *{box-sizing:border-box}
  html,body{height:100%}
  body{
    margin:0;background:var(--paper);color:var(--ink);
    font-family:var(--font-ui);font-size:14px;
    overflow:hidden;user-select:none;-webkit-user-select:none;
  }
  button{font-family:var(--font-ui)}
  #app{display:flex;flex-direction:column;height:100vh}

  /* ---------- top bar ----------
     The bar scrolls sideways at EVERY width rather than only below 680px,
     because "Untitled circui…" clipped against the viewport edge with no
     scrollbar and no fade was a button nobody could reach and nobody could
     see was there. #topbar-wrap is the fixed frame the affordances hang on:
     a pseudo-element fade at each overflowing edge and a chevron that
     scrolls towards it. Both appear only when there is really more to see,
     which updateToolbarOverflow() in js/01-editor.js decides. */
  #topbar-wrap{position:relative;flex:none;display:flex;min-width:0}
  #topbar{
    display:flex;align-items:center;gap:8px;
    height:52px;padding:0 12px;flex:1;min-width:0;
    background:var(--panel);border-bottom:1px solid var(--line);
    overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
    scroll-behavior:smooth;
  }
  #topbar::-webkit-scrollbar{height:0}
  #topbar > *{flex:none}
  #topbar-wrap::before,#topbar-wrap::after{
    content:'';position:absolute;top:0;bottom:1px;width:56px;
    pointer-events:none;opacity:0;transition:opacity .16s ease;z-index:3;
  }
  #topbar-wrap::before{left:0;background:linear-gradient(90deg,var(--panel) 32%,transparent)}
  #topbar-wrap::after{right:0;background:linear-gradient(270deg,var(--panel) 32%,transparent)}
  #topbar-wrap.can-left::before,#topbar-wrap.can-right::after{opacity:1}
  .tb-scroll{
    position:absolute;top:50%;transform:translateY(-50%);z-index:4;
    width:26px;height:30px;display:none;place-items:center;
    border:1px solid var(--line);border-radius:8px;
    background:var(--panel-2);color:var(--ink-deep);
    font-size:16px;line-height:1;cursor:pointer;padding:0;
  }
  .tb-scroll:hover{border-color:var(--accent);color:var(--accent-deep)}
  .tb-scroll.left{left:4px}
  .tb-scroll.right{right:4px}
  #topbar-wrap.can-left .tb-scroll.left,
  #topbar-wrap.can-right .tb-scroll.right{display:grid}
  #logo{display:flex;align-items:center;gap:9px;padding-right:4px;cursor:pointer;border-radius:8px;user-select:none}
  #logo:hover .mark{transform:scale(1.06)}
  #logo:focus-visible{outline:2px solid var(--brand-lime-mid);outline-offset:2px}
  /* the mark is the artwork itself — no tile behind it, or the gradient is
     fighting a coloured box for the same 28 pixels */
  #logo .mark{
    width:30px;height:30px;display:grid;place-items:center;flex:none;
    transition:transform .18s ease;
  }
  #logo .mark svg{width:100%;height:100%;display:block}
  #logo .brand-txt{display:flex;flex-direction:column;justify-content:center;gap:3px;min-width:0}
  /* The wordmark is white pixel letters lit by a cyan glow — which needs
     something dark behind it, exactly as the artwork is drawn. The navy plate
     IS the dark background the logo assumes; on the bare panel white-on-white
     would be nothing but the glow. */
  #logo .name{
    display:block;background:var(--brand-navy);border-radius:5px;
    padding:5px 8px;color:#fff;line-height:0;
    box-shadow:0 0 0 1px rgba(0,151,178,.55), 0 0 11px rgba(0,193,224,.42);
  }
  #logo .name svg{
    display:block;height:11px;width:auto;
    filter:drop-shadow(0 0 2.5px rgba(120,229,255,.95)) drop-shadow(0 0 6px rgba(0,183,214,.65));
  }
  #logo .tagline{
    font-family:var(--font-ui);font-size:7.5px;font-weight:600;line-height:1;
    letter-spacing:.22em;text-transform:uppercase;color:var(--ink-faint);
    white-space:nowrap;padding-left:1px;
  }
  @media (max-width:900px){ #logo .tagline{display:none} }
  #docname{
    font-family:var(--font-ui);font-size:13.5px;font-weight:500;color:var(--ink);
    border:1px solid transparent;background:transparent;border-radius:6px;
    padding:5px 8px;width:150px;flex:none;
  }
  #docname:hover{border-color:var(--line)}
  #docname:focus{outline:none;border-color:var(--copper);background:var(--panel-2)}
  .tb-sep{width:1px;height:26px;background:var(--line);flex:none}
  .tb-btn{
    display:inline-flex;align-items:center;gap:6px;
    height:32px;padding:0 9px;border:1px solid transparent;border-radius:7px;
    background:transparent;color:var(--ink);font-size:12.5px;font-weight:500;cursor:pointer;
    white-space:nowrap;flex:none;
  }
  .tb-btn:hover{background:var(--line-soft)}
  .tb-btn:active{background:var(--line)}
  .tb-btn:disabled{opacity:.35;cursor:default;background:transparent}
  .tb-btn.on{background:var(--copper-soft);border-color:var(--copper)}
  .tb-btn.danger:hover{background:#f6e2e2;color:var(--danger)}
  /* the Run button takes the accent; its deep shade carries white text at AA */
  #btn-sim{
    background:var(--accent-deep);color:#fff;font-weight:600;padding:0 13px;height:33px;
  }
  #btn-sim:hover{background:#005265}
  #btn-sim.running{background:var(--danger)}
  #btn-sim.running:hover{background:#a13030}
  .wc{
    width:15px;height:15px;border-radius:50%;cursor:pointer;flex:none;
    border:2px solid rgba(34,39,46,.18);padding:0;
  }
  .wc.on{border-color:var(--ink);box-shadow:0 0 0 2px var(--panel),0 0 0 3.5px var(--copper)}
  #topbar .spacer{flex:1}

  /* ---------- main ---------- */
  #main{display:flex;flex:1;min-height:0}

  /* ---------- palette ---------- */
  #palette{
    width:216px;flex:none;background:var(--panel);border-right:1px solid var(--line);
    display:flex;flex-direction:column;min-height:0;
  }
  /* the code editor needs room, so the pane widens for it */
  #palette.on-code{width:min(46vw,470px)}
  #pal-tabs{
    flex:none;display:flex;gap:2px;padding:8px 8px 0;border-bottom:1px solid var(--line);
  }
  .pal-tab{
    border:0;background:none;padding:7px 13px 8px;border-radius:8px 8px 0 0;cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;font-weight:500;color:var(--ink-soft);
    border-bottom:2px solid transparent;margin-bottom:-1px;
  }
  .pal-tab:hover{color:var(--ink);background:var(--line-soft)}
  .pal-tab.on{
    color:var(--copper-deep);font-weight:600;border-bottom-color:var(--copper);
    background:var(--panel-2);
  }
  .pal-tab[hidden]{display:none}
  #pal-parts{flex:1;min-height:0;display:flex;flex-direction:column}
  #pal-parts[hidden]{display:none}
  #pal-code{flex:1;min-height:0;display:flex;flex-direction:column}
  #pal-code[hidden]{display:none}
  /* Expand — the code/blocks panel fills the screen. It is the same element,
     lifted out of the flex row, so nothing about the editor changes. */
  /* absolute inside #main, not fixed to the window — the toolbar above stays
     reachable, so Run and Steps are still one click away while reading. */
  body.code-max #main{position:relative}
  body.code-max #palette.on-code{
    position:absolute;inset:0;width:auto;max-width:none;z-index:70;border-right:0;
  }
  body.code-max #pal-code,body.code-max #pal-tabs{width:100%;max-width:1080px;margin:0 auto}
  body.code-max #sketch{font-size:14px;line-height:1.6}
  #code-lock{
    font-size:10.5px;font-weight:600;color:#8a5a1e;background:#f6e7cf;
    border:1px solid #e2c79c;border-radius:999px;padding:2px 8px;white-space:nowrap;
  }
  #code-lock[hidden]{display:none}
  /* why there is no Blocks tab — the alternative is a tab that silently vanishes */
  #code-only{
    font-size:10.5px;color:var(--ink-soft);background:var(--line-soft);
    border:1px solid var(--line);border-radius:999px;padding:2px 8px;
    max-width:230px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:help;
  }
  #code-only[hidden]{display:none}
  /* a guided project writes the program; the learner reads it */
  body.train-mode #code-example{display:none}
  body.train-mode #sketch{background:#262a30;color:#dfe4dc}
  #blocks-pane.ro .bfld{
    background:var(--panel-2);color:var(--ink);opacity:1;-webkit-text-fill-color:var(--ink);
    border-color:var(--line);cursor:default;
  }
  #blocks-pane.ro .blk-grip{cursor:default}
  .blocks-note{
    flex:0 0 auto;font-size:12.5px;line-height:1.65;color:var(--ink-soft);
    background:var(--panel-2);border:1px solid var(--line);border-radius:11px;padding:12px 14px;
  }
  .blocks-note b{color:var(--ink)}
  /* the code panel fills the pane once it has been moved in here */
  #pal-code > .dock-body{flex:1;min-height:0;display:flex;flex-direction:column}
  #pal-search{padding:10px 10px 6px}
  #pal-search input{
    width:100%;height:30px;border:1px solid var(--line);border-radius:7px;
    background:var(--panel-2);padding:0 9px;font-family:var(--font-ui);font-size:12.5px;color:var(--ink);
  }
  #pal-search input:focus{outline:none;border-color:var(--copper)}
  #pal-list{flex:1;overflow-y:auto;padding:2px 10px 14px}
  .pal-cat{
    font-family:var(--font-display);font-weight:600;font-size:11px;letter-spacing:.12em;
    text-transform:uppercase;color:var(--ink-soft);margin:12px 2px 6px;
  }
  .pal-grid{display:grid;grid-template-columns:1fr 1fr;gap:7px}
  .pal-item{
    background:var(--panel-2);border:1px solid var(--line);border-radius:9px;
    padding:7px 5px 6px;text-align:center;cursor:grab;
  }
  .pal-item:hover{border-color:var(--copper);box-shadow:var(--shadow)}
  .pal-item.pending{border-color:var(--copper);background:var(--copper-soft)}
  .pal-item svg{display:block;margin:0 auto;height:38px;width:76px;pointer-events:none}
  .pal-item .pl{font-size:10.5px;color:var(--ink-soft);margin-top:4px;line-height:1.15;pointer-events:none}
  .pal-stage{
    background:var(--copper-soft);border:1px solid #A9D9E4;border-radius:9px;
    padding:9px 10px;margin:2px 0 10px;font-size:11.5px;line-height:1.45;color:#7d3f1c;
  }
  .pal-stage b{display:block;font-size:12.5px;margin-bottom:2px;color:var(--copper-deep)}
  .pal-toggle{
    margin-top:7px;border:1px solid var(--accent);background:var(--panel-2);border-radius:7px;
    padding:4px 9px;font-family:var(--font-ui);font-size:11px;color:var(--copper-deep);cursor:pointer;
  }
  .pal-toggle:hover{border-color:var(--copper)}
  /* Dimming the PARTS list while the simulation runs says "you cannot add a
     component now", which is true. The Code and Blocks tabs live in the
     same panel and are the opposite case: watching the program run while
     reading the blocks that made it is the whole point of pressing Run. */
  body.sim #palette:not(.on-code){opacity:.45;pointer-events:none}

  /* ---------- canvas ---------- */
  #canvas-wrap{position:relative;flex:1;min-width:0;background:var(--canvas)}
  #canvas{
    position:absolute;inset:0;width:100%;height:100%;display:block;
    touch-action:none;cursor:default;
  }
  #canvas.panning{cursor:grabbing}
  #canvas.wiring{cursor:crosshair}
  #canvas.placing{cursor:copy}

  .term{fill:transparent;stroke:transparent;stroke-width:6;cursor:crosshair}
  .comp:hover .term:not(.hole){fill:var(--pin-soft);stroke:rgba(22,160,107,.4);stroke-width:2}
  #canvas.wiring .term:not(.hole){fill:var(--pin-soft);stroke:rgba(22,160,107,.4);stroke-width:2}
  .term:hover{fill:rgba(22,160,107,.55) !important;stroke:var(--pin) !important;stroke-width:2 !important}
  .term.hole{fill:#33363b;stroke:transparent;stroke-width:5}
  .term.hole:hover{fill:var(--pin) !important;stroke:var(--pin-soft) !important;stroke-width:4 !important}
  #canvas.wiring .term.hole{fill:#3c5a4c}
  body.sim .term{pointer-events:none;cursor:default}
  body.sim .comp:hover .term:not(.hole){fill:transparent;stroke:transparent}

  .comp{cursor:move}
  body.sim .comp{cursor:default}
  body.sim .comp.interactive{cursor:pointer}
  .comp.burnt{filter:grayscale(1) brightness(.72)}
  .wire-hit{fill:none;stroke:transparent;stroke-width:11;cursor:pointer;stroke-linecap:round}
  .wire-line{fill:none;stroke-linecap:round;pointer-events:none}
  .wire.sel .wire-line{filter:drop-shadow(0 0 2.5px rgba(192,95,44,.9))}
  .wire-preview{fill:none;stroke-linecap:round;pointer-events:none;opacity:.75}
  .sel-box{fill:none;stroke:var(--copper);stroke-width:1.4;stroke-dasharray:5 4;pointer-events:none}
  .wire-handle{fill:#fff;stroke:var(--copper);stroke-width:1.6;cursor:move}
  .wire-handle:hover{fill:var(--copper-soft)}
  .ghost{opacity:.55;pointer-events:none}
  .comp-label{font-family:var(--font-mono);font-size:9px;fill:#79806f;pointer-events:none}
  .led-halo{pointer-events:none}
  .snap-mark{fill:none;stroke:var(--pin);stroke-width:1.6;pointer-events:none}
  /* --- mechanical joints --- */
  .joint-ring{fill:none;stroke:var(--copper);stroke-width:2.4;pointer-events:none;
              stroke-dasharray:4 3;animation:jointSpin 3s linear infinite}
  .joint-dot{fill:var(--copper);pointer-events:none}
  .joint-flash{fill:none;stroke:var(--live);stroke-width:3;pointer-events:none;
               animation:jointPop 1.4s ease-out forwards}
  .joint-bolt{fill:#e8eaec;stroke:#6c757d;stroke-width:1.3;pointer-events:none;opacity:.95}
  .joint-bolt-in{fill:#6c757d;pointer-events:none}
  /* a driven joint reads as a shaft rather than a bolt */
  .joint-shaft{fill:none;stroke:#8f959c;stroke-width:3.2;pointer-events:none;opacity:.75;stroke-linecap:round}
  .joint-shaft-end{fill:#cfd4d9;stroke:#6c757d;stroke-width:1.3;pointer-events:none}
  .joint-key{fill:#6c757d;pointer-events:none}
  .joint-lead{fill:none;stroke:var(--copper);stroke-width:1.6;stroke-dasharray:5 4;
              opacity:.8;pointer-events:none}
  .joint-plug{fill:none;stroke:var(--copper);stroke-width:2;pointer-events:none;opacity:.9}
  .joint-link{fill:none;stroke:var(--copper);stroke-width:1.4;stroke-dasharray:4 4;
              opacity:.55;pointer-events:none}
  .mech-rel{font-size:11.5px;line-height:1.65;color:var(--ink-soft)}
  .mech-rel .mr-row{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .mech-rel .mr-arrow{color:var(--ink-faint);font-family:var(--font-mono);font-size:10.5px}
  .mech-rel i{color:var(--ink-faint);font-style:normal}
  .joint-open{fill:none;stroke:var(--pin);stroke-width:1.6;stroke-dasharray:3 3;
              opacity:.8;pointer-events:none}
  @keyframes jointSpin{ to{ stroke-dashoffset:-28 } }
  @keyframes jointPop{ 0%{opacity:1;r:8} 100%{opacity:0;r:26} }
  @media (prefers-reduced-motion:reduce){
    .joint-ring,.joint-flash{animation:none}
  }

  /* ---------- zoom bar ---------- */
  #mw-prompt{
    position:absolute;left:50%;transform:translateX(-50%);top:14px;z-index:12;
    max-width:min(460px,80%);
  }
  #mw-prompt[hidden]{display:none}
  #mw-prompt .mw-ready{margin:0;box-shadow:var(--shadow)}
  body.sim #mw-prompt{display:none}

  #zoombar{
    position:absolute;left:12px;bottom:12px;display:flex;align-items:center;gap:2px;
    background:var(--panel);border:1px solid var(--line);border-radius:8px;
    box-shadow:var(--shadow);padding:3px;
  }
  #zoombar button{
    width:28px;height:26px;border:0;background:transparent;border-radius:6px;
    cursor:pointer;color:var(--ink);font-size:15px;display:grid;place-items:center;
  }
  #zoombar button:hover{background:var(--line-soft)}
  #zoom-pct{font-family:var(--font-mono);font-size:11px;color:var(--ink-soft);width:44px;text-align:center}

  #hint{
    position:absolute;left:calc(50% - var(--rp)/2);bottom:14px;transform:translateX(-50%);
    background:rgba(34,39,46,.86);color:#f2f3ee;font-size:12px;
    padding:6px 14px;border-radius:999px;pointer-events:none;white-space:nowrap;
    opacity:0;transition:opacity .15s;max-width:70vw;overflow:hidden;text-overflow:ellipsis;
  }
  #hint.show{opacity:1}

  /* ---------- properties ---------- */
  #props{
    position:absolute;top:12px;right:calc(12px + var(--rp));width:232px;
    background:var(--panel);border:1px solid var(--line);border-radius:11px;
    box-shadow:var(--shadow);overflow:hidden;transition:right .18s;
  }
  #props[hidden]{display:none}
  #props .ph{
    display:flex;align-items:center;justify-content:space-between;
    padding:9px 12px 8px;border-bottom:1px solid var(--line);
  }
  #props .ph .t{font-family:var(--font-display);font-weight:600;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft)}
  #props .pb{padding:10px 12px 12px;display:flex;flex-direction:column;gap:9px}
  .prow{display:flex;flex-direction:column;gap:4px}
  .prow label{font-size:11px;color:var(--ink-soft)}
  .prow input[type=text],.prow input[type=number],.prow select{
    height:29px;border:1px solid var(--line);border-radius:6px;background:var(--panel-2);
    padding:0 8px;font-family:var(--font-ui);font-size:12.5px;color:var(--ink);width:100%;
  }
  .prow input[type=range]{width:100%;accent-color:var(--copper)}
  .prow input:focus,.prow select:focus{outline:none;border-color:var(--copper)}
  .prow .duo{display:flex;gap:6px}
  .prow .duo input{flex:1.4}
  .prow .duo select{flex:1}
  .pactions{display:flex;gap:6px;margin-top:2px}
  .pactions .tb-btn{border:1px solid var(--line);background:var(--panel-2);flex:1;justify-content:center}
  .swatches{display:flex;gap:6px;flex-wrap:wrap}
  .readout{
    display:flex;justify-content:space-between;font-family:var(--font-mono);font-size:12px;
    padding:3px 0;border-bottom:1px dotted var(--line);
  }
  .readout span:first-child{color:var(--ink-soft)}
  .readout b{font-weight:500;font-variant-numeric:tabular-nums}
  .warn{
    background:#f8e6e1;border:1px solid #e6b8a8;color:#9a3d20;border-radius:7px;
    padding:6px 8px;font-size:11.5px;line-height:1.4;
  }

  /* ---------- right dock (code / AI) ---------- */
  #dock{
    position:absolute;top:0;right:0;bottom:0;width:392px;
    background:var(--panel);border-left:1px solid var(--line);
    display:flex;flex-direction:column;z-index:20;
  }
  #dock[hidden]{display:none}
  .dock-head{
    display:flex;align-items:center;gap:8px;height:44px;flex:none;
    padding:0 8px 0 14px;border-bottom:1px solid var(--line);
  }
  .dock-head .dt{font-family:var(--font-display);font-weight:600;font-size:13.5px;flex:1}
  .icon-btn{
    width:28px;height:28px;border:0;background:transparent;border-radius:6px;cursor:pointer;
    color:var(--ink-soft);font-size:16px;display:grid;place-items:center;flex:none;
  }
  .icon-btn:hover{background:var(--line-soft);color:var(--ink)}

  /* code panel */
  #code-bar{
    display:flex;align-items:center;gap:6px;padding:7px 10px;border-bottom:1px solid var(--line-soft);
    font-size:11.5px;color:var(--ink-soft);
  }
  #code-bar select{
    height:26px;border:1px solid var(--line);border-radius:6px;background:var(--panel-2);
    font-family:var(--font-ui);font-size:11.5px;color:var(--ink);padding:0 6px;
  }
  #sketch{
    flex:1;min-height:120px;resize:none;border:0;outline:none;
    background:#22262c;color:#e7ebe4;font-family:var(--font-mono);font-size:12px;line-height:1.55;
    padding:10px 12px;tab-size:2;user-select:text;
  }
  /* ---------- block editor ---------- */
  /* a scrollbar you can actually see, down the right of the code panel */
  #blocks-pane{
    scrollbar-width:auto;scrollbar-color:#a8b0a3 #dfe3da;
    padding-right:6px;
  }
  #blocks-pane::-webkit-scrollbar{width:13px}
  #blocks-pane::-webkit-scrollbar-track{background:#dfe3da;border-radius:8px;margin:4px 0}
  #blocks-pane::-webkit-scrollbar-thumb{
    background:#a8b0a3;border:3px solid #dfe3da;border-radius:8px;min-height:36px;
  }
  #blocks-pane::-webkit-scrollbar-thumb:hover{background:#8d968a}

  /* the add button sits at the top and stays there while you scroll */
  .blocks-top{
    flex:0 0 auto;position:sticky;top:0;z-index:6;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
    background:var(--paper);padding:2px 0 10px;margin-bottom:-4px;
  }
  .btn.add-top{height:36px;font-size:13px;padding:0 16px}
  .blocks-tip{font-size:11px;color:var(--ink-soft)}

  /* the generated sketch, boxed off from the blocks above it */
  .peek-box{
    flex:0 0 auto;border:2px solid #3a4048;border-radius:12px;overflow:hidden;background:#22262c;
    margin-top:2px;
  }
  .peek-head{
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    padding:8px 10px 8px 12px;background:#2c313a;color:#e7ebe4;
    font-family:var(--font-display);font-size:12px;font-weight:600;
  }
  .peek-head .btn{background:transparent;border-color:#4a515b;color:#cfd6cc}
  .peek-head .btn:hover{border-color:#7f8a80;color:#fff}
  .peek-box .peek-code{
    margin:0;border-radius:0;max-height:270px;overflow:auto;border-top:1px solid #3a4048;
  }
  .peek-box .peek-code::-webkit-scrollbar{width:11px}
  .peek-box .peek-code::-webkit-scrollbar-track{background:#2c313a}
  .peek-box .peek-code::-webkit-scrollbar-thumb{background:#565e69;border:3px solid #2c313a;border-radius:7px}
  .blk-add{font-size:11px;padding:4px 9px}
  .blocks-hint{
    font-size:11.5px;line-height:1.5;color:var(--ink-soft);background:var(--panel);
    border:1px solid var(--line-soft);border-radius:9px;padding:8px 11px;
  }
  .blocks-hint b{color:var(--ink)}
  .stack-title{font-size:13.5px}
  .stack-empty{
    font-size:11.5px;color:var(--ink-faint);padding:3px 2px 1px;
  }
  .blk-add.big{
    align-self:stretch;text-align:center;padding:9px 10px;font-size:12.5px;font-weight:500;
    border-width:2px;
  }
  .blk-x{opacity:.75;transition:opacity .12s,background .12s}
  .blk:hover .blk-x,.blk:focus-within .blk-x{opacity:1}
  /* on a C block the cross removes the whole thing, so give it a matching one
     at the closing edge as well — the end of the block is where you look */
  .blk-foot{
    display:flex;align-items:center;justify-content:space-between;gap:8px;
    height:auto;min-height:9px;padding:3px 8px 5px;
  }
  .blk-foot .foot-label{font-size:10.5px;color:#fff;opacity:.75}
  .blk-foot .blk-x{width:18px;height:18px;font-size:10px}
  #blocks-pane{
    flex:1;min-height:0;overflow-y:auto;padding:12px;background:var(--paper);
    display:flex;flex-direction:column;gap:14px;
  }
  #blocks-pane[hidden]{display:none}
  #code-bar .seg{display:inline-flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}
  #code-bar .seg button{
    border:0;background:var(--panel-2);font-family:var(--font-ui);font-size:11.5px;
    padding:4px 11px;cursor:pointer;color:var(--ink-soft);
  }
  #code-bar .seg button.on{background:var(--copper);color:#fff;font-weight:600}
  .stack{
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;overflow:hidden;
    flex:0 0 auto;                 /* never shrink — the panel scrolls instead */
  }
  .stack-head{
    padding:9px 12px;font-family:var(--font-display);font-size:13px;font-weight:600;color:#fff;
    display:flex;align-items:baseline;gap:8px;
  }
  .stack-head.cat-hat{background:#7a6ea8}
  .stack-head.cat-loop{background:#54700B}
  .stack-note{font-family:var(--font-ui);font-size:11px;font-weight:400;opacity:.85}
  .blk-body{padding:8px 8px 8px 10px;display:flex;flex-direction:column;gap:6px;min-height:14px}
  .blk-body.root{padding:10px}
  .blk{
    border-radius:9px;border:1px solid rgba(0,0,0,.12);position:relative;
    box-shadow:0 1px 0 rgba(0,0,0,.06);
  }
  .blk-head{
    display:flex;align-items:center;flex-wrap:wrap;gap:5px;padding:7px 8px 7px 6px;
    font-size:12px;color:#fff;border-radius:8px;
  }
  .blk.cblock > .blk-head{border-radius:8px 8px 0 0}
  .cat-output > .blk-head, .bm-item.cat-output{background:#2e9e56}
  .cat-control > .blk-head, .bm-item.cat-control{background:#e2762c}
  .cat-vars   > .blk-head, .bm-item.cat-vars{background:#8e5bb5}
  .cat-output{background:#2e9e56} .cat-control{background:#e2762c} .cat-vars{background:#8e5bb5}
  .blk .lbl{opacity:.95;white-space:nowrap}
  .blk .grip{cursor:grab;opacity:.7;font-size:11px;letter-spacing:-2px;padding:0 2px;user-select:none}
  .blk .grip:active{cursor:grabbing}
  .blk-x{
    margin-left:auto;border:0;background:rgba(255,255,255,.22);color:#fff;border-radius:5px;
    width:19px;height:19px;font-size:11px;cursor:pointer;line-height:1;flex:none;
  }
  .blk-x:hover{background:rgba(255,255,255,.4)}
  .bfld{
    border:0;border-radius:5px;background:rgba(255,255,255,.92);color:var(--ink);
    font-family:var(--font-ui);font-size:11.5px;padding:2px 5px;height:22px;max-width:130px;
  }
  .bfld.num{width:60px;text-align:center}
  .bfld.txt{width:84px}
  .bfld.kind{background:rgba(255,255,255,.8);font-style:italic}
  .bfld.op{width:44px;text-align:center}
  .bfld:focus{outline:2px solid rgba(255,255,255,.85)}
  .vslot{display:inline-flex;align-items:center;gap:4px;background:rgba(0,0,0,.14);border-radius:6px;padding:2px 4px}
  .blk.cblock{padding-bottom:0}
  .blk.cblock > .blk-body{background:rgba(255,255,255,.9);margin:0 4px;border-radius:0}
  .blk-mid{padding:4px 10px;font-size:11.5px;color:#fff;opacity:.95}
  .blk-foot{height:9px;border-radius:0 0 8px 8px}
  .blk-add{
    align-self:flex-start;border:1px dashed var(--line);background:transparent;border-radius:8px;
    padding:5px 10px;font-family:var(--font-ui);font-size:11.5px;color:var(--ink-soft);cursor:pointer;
  }
  .blk-add:hover{border-color:var(--copper);color:var(--copper)}
  .drop-line{height:4px;border-radius:2px;background:var(--copper);margin:1px 0;animation:none}
  body.dragging-block{cursor:grabbing}
  body.dragging-block .bfld{pointer-events:none}
  .peek{flex:0 0 auto;padding:0 2px 4px}
  .peek-code{
    margin:8px 0 0;background:#22262c;color:#e7ebe4;border-radius:10px;padding:10px 12px;
    font-family:var(--font-mono);font-size:11px;line-height:1.5;overflow-x:auto;white-space:pre;
    user-select:text;
  }
  .blk-menu{display:flex;flex-direction:column;gap:4px;max-height:52vh;overflow-y:auto}
  .bm-cat{
    font-family:var(--font-display);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
    color:var(--ink-soft);margin:10px 0 2px;
  }
  .bm-items{display:flex;flex-wrap:wrap;gap:6px}
  .bm-item{
    border:0;border-radius:8px;color:#fff;padding:7px 11px;font-family:var(--font-ui);
    font-size:12px;cursor:pointer;
  }
  .bm-item:hover{filter:brightness(1.08)}
  #serial-head{
    display:flex;align-items:center;gap:6px;padding:6px 10px;
    border-top:1px solid var(--line);background:var(--panel);
    font-family:var(--font-display);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);
  }
  #serial{
    height:150px;flex:none;overflow-y:auto;background:#191c20;color:#c9d6c8;
    font-family:var(--font-mono);font-size:11.5px;line-height:1.5;padding:8px 12px;
    white-space:pre-wrap;word-break:break-word;user-select:text;
  }
  #serial .err{color:#ff9c8a}
  #serial .sys{color:#8f9a8c}


  /* ---------- help ---------- */
  #help-backdrop{position:fixed;inset:0;background:rgba(34,39,46,.4);display:grid;place-items:center;z-index:50}
  #help-backdrop[hidden]{display:none}
  #help{
    width:min(560px,92vw);max-height:88vh;overflow-y:auto;background:var(--panel);border-radius:14px;
    box-shadow:var(--shadow-pop-lg);padding:20px 22px;
  }
  #help h2{font-family:var(--font-display);font-size:17px;margin:0 0 4px}
  #help h3{font-family:var(--font-display);font-size:12px;letter-spacing:.1em;text-transform:uppercase;
           color:var(--ink-soft);margin:16px 0 6px}
  #help p{margin:4px 0 10px;color:var(--ink-soft);font-size:12.5px;line-height:1.55}
  #help table{width:100%;border-collapse:collapse;font-size:12.5px}
  #help td{padding:4px 0;border-bottom:1px solid var(--line-soft);vertical-align:top}
  #help td:first-child{color:var(--ink-soft);width:52%}
  #help kbd{
    font-family:var(--font-mono);font-size:11px;background:var(--panel-2);
    border:1px solid var(--line);border-bottom-width:2px;border-radius:5px;padding:1px 6px;
  }
  #help .close{margin-top:16px;width:100%;height:32px;border:0;border-radius:7px;background:var(--copper);color:#fff;font-weight:600;cursor:pointer}
  #help .close:hover{background:var(--copper-deep)}

  #drag-ghost{position:fixed;z-index:100;pointer-events:none;opacity:.8;filter:drop-shadow(0 3px 6px rgba(34,39,46,.25))}
  ::-webkit-scrollbar{width:10px}
  ::-webkit-scrollbar-thumb{background:var(--line);border-radius:6px;border:2px solid var(--panel)}
  ::-webkit-scrollbar-track{background:transparent}
  #serial::-webkit-scrollbar-thumb{background:#3a3f45;border-color:#191c20}
  /* ---------- toolbar extras ---------- */
  .tb-btn.icon{padding:0 7px}
  /* an icon with a small word under its own steam — the label switch says
     what it will DO, so its text changes with the state */
  .tb-btn.with-mini{gap:5px}
  .tb-btn .mini-lbl{font-size:10.5px;font-weight:600;letter-spacing:.01em;color:var(--ink-soft)}
  .tb-btn.with-mini:hover .mini-lbl{color:var(--ink)}
  .tb-btn[hidden],#status-chip[hidden]{display:none}
  /* contextual buttons only take space when something is selected */
  .tb-btn.ctx{display:none}
  body.has-sel .tb-btn.ctx{display:inline-flex}
  body.sim .tb-btn.ctx{display:none}
  .tb-btn.primary{background:var(--copper);color:#fff;font-weight:600}
  .tb-btn.primary:hover{background:var(--copper-deep)}
  #status-chip{
    font-size:11.5px;padding:4px 9px;border-radius:999px;background:var(--line-soft);
    color:var(--ink-soft);white-space:nowrap;flex:none;max-width:170px;overflow:hidden;text-overflow:ellipsis;
  }
  #status-chip.good{background:#dcefe2;color:#1c6b40}
  #status-chip.warn{background:#f8ecd9;color:#8a5a13}
  #pal-search{display:flex;flex-direction:column;gap:6px}
  #pal-level{
    height:27px;border:1px solid var(--line);border-radius:7px;background:var(--panel-2);
    font-family:var(--font-ui);font-size:11.5px;color:var(--ink-soft);padding:0 6px;
  }

  /* ---------- dock tabs ---------- */
  .dock-tabs{
    display:flex;align-items:center;gap:2px;height:42px;flex:none;
    padding:0 6px 0 8px;border-bottom:1px solid var(--line);
  }
  .tcard.is-locked{opacity:.62;cursor:not-allowed;background:var(--panel-2)}
  .tcard.is-locked:hover{transform:none;box-shadow:none;border-color:var(--line)}
  .tcard.is-locked .t-art{filter:grayscale(1)}
  .tcard.is-locked .go{color:var(--ink-soft)}
  .dock-title{
    font-family:var(--font-display);font-size:14.5px;font-weight:600;color:var(--ink);
    padding:7px 4px 7px 8px;letter-spacing:.01em;
  }
  .dock-tab{
    height:30px;padding:0 11px;border:0;border-radius:7px;background:transparent;
    font-family:var(--font-ui);font-size:12.5px;font-weight:500;color:var(--ink-soft);cursor:pointer;
  }
  .dock-tab:hover{background:var(--line-soft);color:var(--ink)}
  .dock-tab.on{background:var(--copper-soft);color:var(--copper-deep);font-weight:600}
  .dock-tab[hidden]{display:none}
  .dock-tab.new::after{
    content:'';display:inline-block;width:6px;height:6px;border-radius:50%;
    background:var(--copper);margin-left:6px;vertical-align:middle;
  }
  #serial{height:auto;flex:1;min-height:0}
  #serial:empty::before{
    content:'Nothing printed yet. Add a “print” block to send readings here.';
    color:#6f7a70;font-family:var(--font-ui);font-size:12px;
  }
  .dock-tab .dot{
    display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--danger);
    margin-left:5px;vertical-align:middle;
  }
  .dock-body{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto}
  .dock-body[hidden]{display:none}
  .dock-body.pad{padding:14px;gap:12px}

  /* ---------- Make it Work: guidance above the blocks ---------- */
  #mw-guide{flex:0 0 auto;padding:12px 12px 0;background:var(--paper)}
  #mw-guide:empty{display:none}
  .mw-steps{
    display:flex;align-items:center;gap:6px;flex-wrap:wrap;
    font-size:11px;color:var(--ink-soft);margin-bottom:10px;
  }
  .mw-steps b{
    display:inline-flex;align-items:center;gap:5px;font-weight:500;
    background:var(--panel-2);border:1px solid var(--line);border-radius:999px;padding:3px 9px;
  }
  .mw-steps b.on{background:var(--copper-soft);border-color:var(--copper);color:var(--copper-deep);font-weight:600}
  .mw-steps i{font-style:normal;opacity:.5}
  .mw-goal{
    background:var(--panel-2);border:1px solid var(--line);border-radius:11px;
    padding:11px 13px;margin-bottom:10px;
  }
  .mw-goal .g-title{
    font-family:var(--font-display);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
    color:var(--copper-deep);margin-bottom:4px;
  }
  .mw-goal .g-text{font-size:13px;line-height:1.5;color:var(--ink)}
  .mw-goal .g-think{
    margin-top:9px;padding-top:9px;border-top:1px dotted var(--line);
    font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);
  }
  .mw-goal ol{margin:6px 0 0;padding-left:20px;font-size:12.5px;line-height:1.65;color:var(--ink-soft)}
  .mw-goal ol li::marker{color:var(--copper);font-weight:600}
  .mw-hintrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
  .mw-hint{
    background:#e7f1fb;border:1px solid #b4d0ea;border-radius:9px;padding:8px 11px;
    font-size:12.5px;line-height:1.55;color:#1f3f5c;margin-top:8px;
  }
  .mw-hint b{display:block;font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:#1f5c93;margin-bottom:3px}
  .mw-solution{background:#e3f2e8;border-color:#a9d3ba;color:#1c4a2e}
  .mw-ready{
    display:flex;align-items:center;gap:10px;flex-wrap:wrap;
    background:#e3f2e8;border:1px solid #a9d3ba;border-radius:11px;padding:10px 13px;margin-bottom:10px;
  }
  .mw-ready .r-txt{font-size:12.5px;color:#1c4a2e;flex:1;min-width:150px;line-height:1.45}
  .mw-ready .r-txt b{display:block;font-weight:600}

  /* the pin, kept visible but quiet, beside every part dropdown */
  .pin-note{
    font-family:var(--font-mono);font-size:9.5px;color:#fff;opacity:.62;
    background:rgba(0,0,0,.22);border-radius:4px;padding:1px 4px;margin-left:1px;cursor:help;
  }
  .bfld.part{max-width:none;font-weight:500}
  .blk-help{
    border:0;background:rgba(255,255,255,.22);color:#fff;border-radius:50%;
    width:17px;height:17px;font-size:10.5px;font-weight:700;cursor:pointer;line-height:1;
    flex:none;margin-left:4px;opacity:.8;
  }
  .blk-help:hover{background:rgba(255,255,255,.45);opacity:1}
  .blk.linked > .blk-head{outline:2px solid var(--copper);outline-offset:1px}

  /* the block -> code reveal */
  .xlate{display:flex;flex-direction:column;gap:6px;padding:2px 0 6px}
  .xlate .x-row{display:flex;align-items:center;gap:8px;font-size:12px}
  .xlate .x-blk{
    background:#2e9e56;color:#fff;border-radius:7px;padding:4px 9px;font-size:11.5px;flex:none;
  }
  .xlate .x-arrow{color:var(--ink-faint);font-size:13px}
  .xlate .x-code{
    font-family:var(--font-mono);font-size:11px;color:#cfe3d5;background:#22262c;
    border-radius:6px;padding:4px 8px;flex:1;overflow-x:auto;white-space:pre;
  }
  .stage-pick{display:flex;gap:6px;flex-wrap:wrap;margin:2px 0 8px}
  .stage-pick button{
    border:1px solid var(--line);background:var(--panel-2);border-radius:999px;
    padding:5px 12px;font-family:var(--font-ui);font-size:12px;color:var(--ink-soft);cursor:pointer;
  }
  .stage-pick button.on{background:var(--copper);border-color:var(--copper);color:#fff;font-weight:600}
  .stage-blurb{font-size:11.5px;color:var(--ink-soft);margin-bottom:4px}
  .ex-grid{display:grid;gap:9px;grid-template-columns:1fr 1fr;margin-top:4px}
  @media (max-width:520px){ .ex-grid{grid-template-columns:1fr} }
  .ex-card{
    background:var(--panel-2);border:1px solid var(--line);border-radius:11px;padding:11px 12px;
    text-align:left;font:inherit;color:inherit;cursor:pointer;display:flex;flex-direction:column;gap:4px;
  }
  .ex-card:hover{border-color:var(--copper);box-shadow:var(--shadow)}
  .ex-card .e-em{font-size:20px;line-height:1}
  .ex-card .e-name{font-family:var(--font-display);font-size:13px;font-weight:600}
  .ex-card .e-sub{font-size:11.5px;color:var(--ink-soft);line-height:1.45}
  .ex-learn{display:flex;flex-wrap:wrap;gap:5px;margin-top:2px}
  .ex-learn span{background:var(--line-soft);border-radius:999px;padding:2px 8px;font-size:10.5px;color:var(--ink-soft)}

  /* ---------- teaching cards ---------- */
  .card{
    background:var(--panel-2);border:1px solid var(--line);border-radius:11px;padding:12px 13px;
  }
  .card h4{margin:0 0 6px;font-family:var(--font-display);font-size:13.5px;font-weight:600}
  .card p{margin:0 0 8px;font-size:12.5px;line-height:1.55;color:var(--ink-soft)}
  .card p:last-child{margin-bottom:0}
  .card.err{background:#fbe9e4;border-color:#e8b9a6}
  .card.warn{background:#fcf1dd;border-color:#e8cf9c}
  .card.hint{background:#e7f1fb;border-color:#b4d0ea}
  .card.info{background:var(--panel-2)}
  .card.ok{background:#e3f2e8;border-color:#a9d3ba}
  .sev{
    display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:600;
    letter-spacing:.09em;text-transform:uppercase;margin-bottom:5px;
  }
  .sev.err{color:#B3261E} .sev.warn{color:#8a5a13} .sev.hint{color:#046A87}
  .sev.info{color:var(--ink-soft)} .sev.ok{color:#0F6B58}
  .fixline{
    margin-top:8px;padding:7px 9px;border-radius:8px;background:rgba(34,39,46,.05);
    font-size:12px;line-height:1.5;
  }
  .fixline b{font-weight:600}
  .empty{
    text-align:center;color:var(--ink-faint);font-size:12.5px;line-height:1.6;padding:26px 16px;
  }
  .empty .big{font-size:28px;display:block;margin-bottom:8px;opacity:.7}

  .studio-ways{display:grid;gap:8px;grid-template-columns:1fr 1fr}
  @media (max-width:520px){ .studio-ways{grid-template-columns:1fr} }
  .studio-ways .sw{
    background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:10px 12px;
    font-size:12px;line-height:1.55;color:var(--ink-soft);
  }
  .studio-ways .sw b{display:block;font-size:13px;color:var(--ink);margin-bottom:3px;font-weight:600}

  /* ---------- the assistant ----------
     Reads what you type, turns it into the commands the canvas already
     understands, and lets the mechanical and electrical rules decide
     whether it is possible. It never invents a connection. */
  #chat{
    position:fixed;right:16px;bottom:16px;width:380px;max-height:min(78vh,740px);z-index:59;
    display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);
    border-radius:14px;box-shadow:var(--shadow-pop);overflow:hidden;
  }
  #chat[hidden]{display:none}
  .ch-head{
    flex:none;display:flex;align-items:center;gap:9px;padding:11px 13px;
    border-bottom:1px solid var(--line);background:var(--panel-2);
  }
  .ch-head b{font-family:var(--font-display);font-size:14.5px}
  .ch-head span{font-size:11.5px;color:var(--ink-faint);flex:1;min-width:0}
  .ch-head .hm-x:first-of-type{margin-left:0}
  #ch-log{flex:1;min-height:0;overflow-y:auto;padding:12px 13px;display:flex;
          flex-direction:column;gap:10px}
  .ch-ask{
    flex:none;display:flex;gap:6px;padding:9px 11px;border-top:1px solid var(--line);
    background:var(--panel-2);
  }
  .ch-ask input{
    flex:1;min-width:0;height:32px;border:1px solid var(--line);border-radius:8px;
    background:var(--panel);padding:0 10px;font-family:var(--font-ui);font-size:12.5px;color:var(--ink);
  }
  .ch-ask input:focus{outline:none;border-color:var(--copper)}

  .ch-you{
    align-self:flex-end;max-width:86%;background:var(--copper);color:#fff;border-radius:12px 12px 3px 12px;
    padding:8px 12px;font-size:12.5px;line-height:1.5;
  }
  .ch-it{
    align-self:flex-start;max-width:92%;background:var(--panel-2);border:1px solid var(--line);
    border-radius:12px 12px 12px 3px;padding:9px 12px;font-size:12.5px;line-height:1.55;color:var(--ink);
  }
  .ch-it.ok{border-color:#bfe0c8;background:#f4faf6}
  .ch-it.no{border-color:#e8b6a6;background:#fbe9e4}
  .ch-it .ch-line{margin:0}
  .ch-it .ch-line + .ch-line{margin-top:3px}
  .ch-it.think{border-color:#c9d6e8;background:#f2f6fb}
  .ch-it.think .ch-line::after{content:'';display:inline-block;width:0;overflow:hidden;
    vertical-align:bottom;animation:chdots 1.2s steps(4,end) infinite}
  @keyframes chdots{to{width:1.2em}}
  .ch-steps{margin:8px 0 0;padding-top:7px;border-top:1px solid rgba(0,0,0,.08);
    font-size:12px;line-height:1.6;color:#5d6b64}
  .ch-steps div{white-space:pre-wrap}
  .ch-it ul{margin:6px 0 0;padding-left:17px}
  .ch-it li{margin:2px 0;line-height:1.5}
  .ch-it .ch-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
  .ch-hint{
    font-size:11.5px;color:var(--ink-faint);line-height:1.5;text-align:center;padding:2px 6px;
  }
  .ch-chips{display:flex;flex-wrap:wrap;gap:5px;justify-content:center;padding:0 4px}
  .ch-chip{
    border:1px solid var(--line);background:var(--panel-2);border-radius:999px;padding:5px 11px;
    font-family:var(--font-ui);font-size:11.5px;color:var(--ink-soft);cursor:pointer;
  }
  .ch-chip:hover{border-color:var(--copper);color:var(--copper-deep)}
  @media (max-width:680px){
    #chat{left:10px;right:10px;bottom:10px;width:auto;max-height:72vh}
  }

  /* ---------- Help me ----------
     A panel beside the canvas, not a chat window. It has to leave the
     canvas visible, because pointing at it is half of what it does. */
  #helpme{
    position:fixed;right:16px;bottom:16px;width:370px;max-height:min(76vh,720px);z-index:58;
    display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);
    border-radius:14px;box-shadow:var(--shadow-pop);overflow:hidden;
  }
  #helpme[hidden]{display:none}
  .hm-head{
    flex:none;display:flex;align-items:center;gap:9px;padding:11px 13px;
    border-bottom:1px solid var(--line);background:var(--panel-2);
  }
  .hm-head b{font-family:var(--font-display);font-size:14.5px}
  .hm-head span{font-size:11.5px;color:var(--ink-faint)}
  .hm-x{
    margin-left:auto;border:0;background:var(--line-soft);color:var(--ink-soft);border-radius:6px;
    width:22px;height:22px;font-size:12px;cursor:pointer;line-height:1;flex:none;
  }
  .hm-x:hover{background:var(--line);color:var(--ink)}
  #hm-body{flex:1;min-height:0;overflow-y:auto;padding:12px 13px;font-size:12.5px;line-height:1.6}
  .hm-ask{
    flex:none;display:flex;gap:6px;padding:9px 11px;border-top:1px solid var(--line);
    background:var(--panel-2);
  }
  .hm-ask input{
    flex:1;min-width:0;height:30px;border:1px solid var(--line);border-radius:8px;
    background:var(--panel);padding:0 10px;font-family:var(--font-ui);font-size:12px;color:var(--ink);
  }
  .hm-ask input:focus{outline:none;border-color:var(--copper)}

  .hm-parts{display:flex;flex-wrap:wrap;gap:5px;margin-bottom:11px}
  .hm-parts .hp{
    background:var(--line-soft);border-radius:999px;padding:3px 9px;font-size:11px;color:var(--ink-soft);
    cursor:pointer;border:1px solid transparent;
  }
  .hm-parts .hp:hover{border-color:var(--copper);color:var(--copper-deep);background:#fff}
  .hm-t{
    font-family:var(--font-display);font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;
    color:var(--ink-faint);margin:0 0 6px;
  }
  .hm-q{
    display:block;width:100%;text-align:left;border:1px solid var(--line);border-radius:9px;
    background:var(--panel-2);padding:9px 11px;margin-bottom:6px;cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;color:var(--ink);line-height:1.4;
  }
  .hm-q:hover{border-color:var(--copper);background:#F3FAFC;color:var(--copper-deep)}

  .hm-card{border:1px solid var(--line);border-radius:11px;background:var(--panel-2);overflow:hidden}
  .hm-card .hc-h{
    padding:10px 12px;font-family:var(--font-display);font-size:13.5px;font-weight:600;
    border-bottom:1px solid var(--line-soft);
  }
  .hm-card.mech .hc-h{background:#f1effa;color:#4b4080}
  .hm-card.elec .hc-h{background:#eaf1fb;color:#28527f}
  .hm-card.bad .hc-h{background:#fbe9e4;color:#a5381c}
  .hm-card.ok .hc-h{background:#eef8f1;color:#1c6b40}
  .hm-card .hc-b{padding:11px 12px}
  .hm-card .hc-b p{margin:0 0 7px}
  .hm-card .hc-b p:last-child{margin-bottom:0}
  .hm-why{
    margin-top:9px;padding:8px 10px;background:var(--panel);border-radius:8px;
    font-size:12px;color:var(--ink-soft);line-height:1.55;
  }
  .hm-why b{color:var(--ink);display:block;font-size:10.5px;letter-spacing:.1em;
            text-transform:uppercase;margin-bottom:2px}
  .hm-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:11px}

  /* the little relationship diagram */
  .hm-chain{
    display:flex;flex-direction:column;align-items:flex-start;gap:2px;margin:9px 0 2px;
    padding:10px 12px;background:var(--panel);border-radius:9px;font-size:12.5px;
  }
  .hm-chain .cn{font-weight:600;color:var(--ink)}
  .hm-chain .cl{color:var(--ink-faint);font-size:11px;padding-left:3px;line-height:1.5}
  .hm-chain .cl b{color:var(--copper-deep);font-weight:600}

  .hm-step{
    display:flex;gap:9px;padding:9px 11px;border:1px solid var(--line);border-radius:9px;
    background:var(--panel-2);margin-bottom:6px;align-items:flex-start;
  }
  .hm-step .sn{
    width:19px;height:19px;border-radius:50%;background:var(--copper);color:#fff;flex:none;
    display:grid;place-items:center;font-size:11px;font-weight:700;
  }
  .hm-step.did .sn{background:var(--live)}
  .hm-step .st{flex:1;min-width:0;font-size:12px;line-height:1.5}
  .hm-hint{
    background:#fcf1dd;border-radius:8px;padding:8px 10px;margin-top:7px;
    font-size:12px;line-height:1.55;color:#8a5a13;
  }
  .hm-hint b{display:block;font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;margin-bottom:2px}

  /* what Show me draws on the canvas */
  .help-ring{
    fill:none;stroke:var(--copper);stroke-width:3;pointer-events:none;
    animation:helpPulse 1.6s ease-in-out infinite;
  }
  .help-label{
    font-family:var(--font-ui);font-size:11px;font-weight:600;fill:var(--copper-deep);
    paint-order:stroke;stroke:var(--paper);stroke-width:3.5;pointer-events:none;
  }
  @keyframes helpPulse{ 0%,100%{r:13;opacity:.95} 50%{r:18;opacity:.55} }
  @media (prefers-reduced-motion:reduce){ .help-ring{animation:none} }

  @media (max-width:680px){
    #helpme{left:10px;right:10px;bottom:10px;width:auto;max-height:70vh}
  }

  /* ---------- the invention workbench ----------
     The right-hand panel is fine for a glance, but not for working in.
     This is the same content given the whole page, with a live view of
     the canvas pinned in the corner so the link between the blocks and
     the invention is never lost. */
  #studio{position:fixed;inset:0;z-index:55;background:var(--paper);display:flex;flex-direction:column}
  #studio[hidden]{display:none}
  #studio-head{
    flex:none;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    padding:11px 18px;background:var(--panel);border-bottom:1px solid var(--line);
  }

  /* ---- the four stages, across the top ---- */
  #studio-rail{
    flex:none;display:flex;align-items:stretch;gap:0;background:var(--panel);
    border-bottom:1px solid var(--line);padding:0 18px;overflow-x:auto;scrollbar-width:none;
  }
  #studio-rail::-webkit-scrollbar{height:0}
  #studio-rail .rs{
    display:flex;align-items:center;gap:8px;padding:12px 16px 11px;border:0;background:none;
    font-family:var(--font-ui);font-size:12.5px;color:var(--ink-faint);cursor:default;
    border-bottom:3px solid transparent;white-space:nowrap;
  }
  #studio-rail .rs em{
    width:21px;height:21px;border-radius:50%;background:var(--line-soft);color:var(--ink-faint);
    display:grid;place-items:center;font-style:normal;font-size:11px;font-weight:700;flex:none;
  }
  #studio-rail .rs.done{color:#1c6b40;cursor:pointer}
  #studio-rail .rs.done em{background:var(--live);color:#fff}
  #studio-rail .rs.done:hover{background:#f2f9f4}
  #studio-rail .rs.now{
    color:var(--copper-deep);border-bottom-color:var(--copper);
    font-family:var(--font-display);font-weight:600;font-size:14px;
  }
  #studio-rail .rs.now em{background:var(--copper);color:#fff}
  #studio-rail .rs-sep{align-self:center;color:var(--line);font-size:12px;flex:none}

  /* ---- footer: one primary action, one way back ---- */
  #studio-foot{
    flex:none;display:flex;align-items:center;gap:12px;padding:11px 18px;
    background:var(--panel);border-top:1px solid var(--line);
  }
  #st-note{font-size:12px;color:var(--ink-soft);line-height:1.4}
  #st-back[hidden],#st-next[hidden]{display:none}

  /* ---- the single content column ---- */
  .wz{max-width:760px;margin:0 auto}
  .wz-h{
    font-family:var(--font-display);font-size:24px;font-weight:700;margin:0 0 5px;line-height:1.2;
  }
  .wz-sub{margin:0 0 22px;font-size:14px;color:var(--ink-soft);line-height:1.6;max-width:56ch}
  .wz-t{
    font-family:var(--font-display);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-faint);margin:22px 0 9px;
  }
  .wz-t:first-child{margin-top:0}

  /* a connection offered to the student */
  .cx{
    display:flex;align-items:center;gap:14px;border:1px solid var(--line);border-radius:12px;
    background:var(--panel-2);padding:14px 16px;margin-bottom:9px;
  }
  .cx.done{border-color:#bfe0c8;background:#f4faf6}
  .cx .cx-pair{font-size:15px;font-weight:600;line-height:1.35}
  .cx .cx-kind{font-size:12px;color:var(--ink-soft);margin-top:3px;line-height:1.45}
  .cx .cx-body{flex:1;min-width:0}
  .cx .cx-act{flex:none}
  .cx.mech{border-left:4px solid #7a6ea8}
  .cx.elec{border-left:4px solid #2f6fce}
  .cx.done{border-left-color:var(--live)}

  /* a part chip in the BUILD stage */
  .pchips{display:flex;flex-wrap:wrap;gap:8px}
  .pchip{
    display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:10px;
    background:var(--panel-2);padding:8px 12px;font-size:13px;
  }
  .pchip svg{width:26px;height:26px;flex:none}
  .pchip .px{
    border:0;background:var(--line-soft);color:var(--ink-soft);border-radius:5px;width:19px;height:19px;
    font-size:11px;cursor:pointer;line-height:1;margin-left:3px;
  }
  .pchip .px:hover{background:#fbe9e4;color:#a5381c}
  .starters{display:grid;gap:9px;grid-template-columns:repeat(auto-fill,minmax(168px,1fr))}
  .starter{
    display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:11px;
    background:var(--panel-2);padding:12px 14px;cursor:pointer;font-family:var(--font-ui);
    font-size:13.5px;color:var(--ink);text-align:left;
  }
  .starter:hover{border-color:var(--copper);background:#F3FAFC}
  .starter b{font-size:19px;flex:none}

  /* a behaviour, as a sentence */
  .bhv{
    display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:11px;
    background:var(--panel-2);padding:12px 15px;margin-bottom:8px;font-size:14px;line-height:1.45;
  }
  .bhv .bx{
    margin-left:auto;border:0;background:var(--line-soft);color:var(--ink-soft);border-radius:5px;
    width:20px;height:20px;font-size:11px;cursor:pointer;line-height:1;flex:none;
  }
  .bhv .bx:hover{background:#fbe9e4;color:#a5381c}
  .bhv.todo{border-style:dashed;border-color:var(--copper);background:#fff6ec}

  /* something needs doing — actionable, never a diagnostic dump */
  .wz-warn{
    display:flex;align-items:center;gap:12px;border:1px solid #e8cf9a;border-radius:11px;
    background:#fcf1dd;padding:12px 15px;margin-bottom:12px;font-size:13.5px;color:#8a5a13;
    line-height:1.45;
  }
  .wz-warn .btn{flex:none;margin-left:auto}

  /* the RUN summary */
  .wz-ready{text-align:center;padding:14px 0 4px}
  .wz-ready h2{font-family:var(--font-display);font-size:28px;margin:0 0 20px;font-weight:700}
  .wz-tally{display:flex;justify-content:center;gap:10px;flex-wrap:wrap;margin-bottom:24px}
  .wz-tally span{
    background:var(--panel-2);border:1px solid var(--line);border-radius:10px;padding:11px 18px;
    font-size:13.5px;color:var(--ink-soft);
  }
  .wz-tally b{display:block;font-family:var(--font-display);font-size:22px;color:var(--ink);font-weight:600}
  .btn.huge{height:56px;padding:0 34px;font-size:17px;border-radius:12px;font-weight:600}
  .wz-adv{
    margin-top:26px;padding-top:16px;border-top:1px solid var(--line-soft);
  }
  .wz-advlink{
    border:0;background:none;color:var(--ink-faint);cursor:pointer;padding:4px 0;
    font-family:var(--font-ui);font-size:12.5px;
  }
  .wz-advlink:hover{color:var(--copper-deep)}
  .sh-title{font-size:13px;color:var(--ink-soft);line-height:1.4}
  .sh-title b{font-family:var(--font-display);font-size:16px;color:var(--ink);font-weight:600;margin-right:8px}
  .sh-title span{display:block;font-size:11.5px;color:var(--ink-faint)}
  #studio-rail{display:flex;gap:4px;flex-wrap:wrap}
  #studio-rail .rs{
    display:flex;align-items:center;gap:6px;border-radius:999px;padding:5px 12px;
    background:var(--line-soft);font-family:var(--font-display);font-size:10px;
    letter-spacing:.07em;text-transform:uppercase;color:var(--ink-faint);
  }
  #studio-rail .rs em{font-style:normal;font-size:11px}
  #studio-rail .rs.done{background:#e6f4ea;color:#1c6b40}
  #studio-rail .rs.now{background:var(--copper);color:#fff}
  #studio-body{flex:1;min-height:0;overflow-y:auto;padding:26px 18px 40px}
  .st-grid{
    max-width:1180px;margin:0 auto;display:grid;gap:18px;
    grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);align-items:start;
  }
  .st-col{display:flex;flex-direction:column;gap:11px;min-width:0}
  .st-col .if-list{gap:9px}
  /* the blocks get room to breathe once they are not in a 470px column */
  #studio .if-say{font-size:14px;padding:8px 13px 11px;gap:6px 8px}
  #studio .if-slot{font-size:13.5px;padding:3px 11px;max-width:280px}
  #studio .if-top{padding:10px 12px 0}
  #studio .if-state{padding:7px 13px;font-size:12px}
  #studio .if-blk{border-left-width:5px}
  #studio .btn.wide.big{height:44px;font-size:14.5px}
  #studio .if-next h5{font-size:13.5px}
  #studio .if-go{font-size:13px;padding:11px 13px}
  #studio .if-status{border:1px solid var(--line);border-radius:12px;background:var(--panel)}
  #studio .iv-metrics{grid-template-columns:1fr 1fr}

  /* the live view of the real canvas — a full card in the right column,
     directly under the status, where the space was going to waste */
  #studio-mini{
    position:fixed;right:18px;bottom:74px;width:258px;z-index:56;
    background:var(--panel);border:1px solid var(--line);border-radius:12px;overflow:hidden;
    box-shadow:var(--shadow-pop-sm);
  }
  #studio-mini.tucked #sm-svg,#studio-mini.tucked .sm-foot{display:none}
  .sm-head{
    display:flex;align-items:center;gap:8px;padding:10px 13px;font-size:12.5px;font-weight:600;
    color:var(--ink);border-bottom:1px solid var(--line-soft);cursor:pointer;
  }
  .sm-head span{margin-left:auto;font-weight:400;color:var(--ink-faint);font-size:11.5px}
  .sm-tidy{
    border:1px solid var(--line);background:var(--panel-2);color:var(--ink-soft);border-radius:7px;
    padding:4px 10px;font-family:var(--font-ui);font-size:11.5px;cursor:pointer;flex:none;
  }
  .sm-tidy:hover{border-color:var(--copper);color:var(--copper-deep)}
  #sm-svg{display:block;width:100%;height:164px;background:var(--canvas)}
  .sm-foot{
    padding:9px 13px 11px;font-size:11.5px;line-height:1.65;color:var(--ink-soft);
    border-top:1px solid var(--line-soft);min-height:10px;
  }
  .sm-foot b{color:var(--copper-deep)}
  .sm-foot .sf-t{
    font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);
    margin-bottom:3px;
  }
  @media (max-width:1100px){ #studio-mini{display:none} }
  @media (max-width:680px){
    #studio-body{padding:16px 14px 30px}
    .wz-h{font-size:20px}
    .wz-sub{font-size:13px;margin-bottom:16px}
    #studio-rail .rs{padding:10px 10px 9px;font-size:11.5px}
    #studio-rail .rs.now{font-size:12.5px}
    #studio-rail .rs-sep{display:none}
    .cx{flex-wrap:wrap}
    .cx .cx-act{width:100%}
    .cx .cx-act .btn{width:100%}
    .btn.huge{height:48px;font-size:15px;width:100%}
  }

  /* while inventing, the canvas offers one obvious action and no dock tabs */
  body.flow-mode #btn-steps,
  body.flow-mode #btn-why,
  body.flow-mode #btn-why-broken,
  /* Restart belongs to a guided project — there is nothing to restart otherwise */
  #btn-restart{display:none}
  body.train-mode #btn-restart{display:inline-flex}

  /* ---------- Training: follow the steps, not the side doors ---------- */
  body.train-mode #btn-why,
  body.train-mode #btn-why-broken{display:none}
  /* the assistant is the Invent experience — it does not appear elsewhere */
  #btn-chat{display:none}
  body.flow-mode #btn-chat{display:inline-flex}

  body.flow-mode .dock-tab[data-tab="steps"],
  body.flow-mode .dock-tab[data-tab="code"],
  body.flow-mode .dock-tab[data-tab="check"],
  body.flow-mode .dock-tab[data-tab="why"]{display:none}
  .tb-btn.primary{
    background:var(--copper);border-color:var(--copper);color:#fff;font-weight:600;
  }
  .tb-btn.primary:hover{background:var(--copper-deep);color:#fff}

  /* ---------- InventFlow ----------
     A white, quiet panel. The canvas is the hero; this is the instruction
     layer beside it, so nothing here shouts louder than the invention. */
  #tab-flow{background:var(--paper)}

  .if-head{flex:0 0 auto;background:var(--panel);border-bottom:1px solid var(--line);padding:12px 13px 10px}
  .if-brand{display:flex;align-items:flex-start;gap:9px}
  .if-brand .if-mark2{font-size:19px;line-height:1.1}
  .if-brand h4{
    margin:0;font-family:var(--font-display);font-size:15px;font-weight:600;letter-spacing:.01em;
  }
  .if-brand .if-tag{display:block;font-family:var(--font-ui);font-size:11.5px;font-weight:400;color:var(--ink-soft);margin-top:1px}
  .if-brand .if-acts{margin-left:auto;display:flex;gap:5px;flex:none}
  .if-help{
    margin:8px 0 0;font-size:11.5px;line-height:1.5;color:var(--ink-faint);
  }
  .if-pipe{
    display:flex;align-items:center;gap:6px;margin-top:8px;font-size:10px;letter-spacing:.09em;
    text-transform:uppercase;font-family:var(--font-display);color:var(--ink-faint);
  }
  .if-pipe b{
    font-weight:600;background:var(--line-soft);border-radius:999px;padding:3px 8px;color:var(--ink-soft);
  }
  .if-pipe b.hot{background:var(--copper);color:#fff}
  .if-pipe i{font-style:normal;opacity:.55}

  /* the four-step orientation rail */
  .if-rail{display:flex;gap:4px;margin-top:10px}
  .if-rail .rs{
    flex:1;min-width:0;text-align:center;border-radius:8px;padding:5px 3px 6px;
    background:var(--line-soft);border:1px solid transparent;
  }
  .if-rail .rs em{
    display:block;font-style:normal;font-size:12px;line-height:1.1;color:var(--ink-faint);
  }
  .if-rail .rs span{
    display:block;font-family:var(--font-display);font-size:9.5px;letter-spacing:.06em;
    text-transform:uppercase;color:var(--ink-faint);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .if-rail .rs.done{background:#e6f4ea}
  .if-rail .rs.done em,.if-rail .rs.done span{color:#1c6b40}
  .if-rail .rs.now{background:#fff;border-color:var(--copper)}
  .if-rail .rs.now em,.if-rail .rs.now span{color:var(--copper-deep)}

  .if-body{flex:1;min-height:0;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:11px}

  /* ---- the coach card: onboarding, celebrations, next steps ---- */
  .if-coach{
    border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:12px 13px;
  }
  .if-coach.warm{background:#fff8f1;border-color:#f0d4b6}
  .if-coach.good{background:#eefaf1;border-color:#bfe4c9}
  .if-coach h5{
    margin:0 0 3px;font-family:var(--font-display);font-size:13.5px;font-weight:600;line-height:1.35;
  }
  .if-coach p{margin:0;font-size:12px;line-height:1.6;color:var(--ink-soft)}
  .if-coach .if-do{display:flex;flex-direction:column;gap:6px;margin-top:10px}
  .if-coach .if-skip{
    margin-top:9px;background:none;border:0;padding:0;color:var(--ink-faint);
    font-family:var(--font-ui);font-size:11px;cursor:pointer;text-decoration:underline;
  }
  .if-coach .if-skip:hover{color:var(--ink-soft)}
  .if-coach .if-dots{display:flex;gap:4px;margin-top:10px}
  .if-coach .if-dots i{width:16px;height:3px;border-radius:2px;background:var(--line);display:block}
  .if-coach .if-dots i.on{background:var(--copper)}

  /* a big, obvious "do this" button that reads like a block */
  .if-go{
    display:flex;align-items:center;gap:9px;width:100%;text-align:left;cursor:pointer;
    border:1px solid var(--line);border-radius:10px;background:#fff;padding:9px 11px;
    font-family:var(--font-ui);font-size:12.5px;color:var(--ink);line-height:1.35;
  }
  .if-go:hover{border-color:var(--copper);box-shadow:0 1px 5px rgba(0,0,0,.07)}
  .if-go .g-ic{font-size:15px;flex:none;width:20px;text-align:center}
  .if-go .g-verb{
    font-family:var(--font-display);font-size:10.5px;font-weight:600;letter-spacing:.08em;
    text-transform:uppercase;color:var(--ink-soft);flex:none;
  }
  .if-go b{font-weight:600}
  .if-go .g-arrow{margin-left:auto;color:var(--ink-faint);flex:none}

  /* ---- blocks: a sentence you can read out loud ---- */
  .if-list{display:flex;flex-direction:column;gap:8px}
  .if-blk{
    border:1px solid var(--line);border-left:4px solid var(--line);border-radius:10px;
    background:var(--panel);overflow:hidden;
  }
  .if-blk.cat-if-build{border-left-color:#2e9e56}
  .if-blk.cat-if-mech{border-left-color:#7a6ea8}
  .if-blk.cat-if-elec{border-left-color:#2f6fce}
  .if-blk.cat-if-control{border-left-color:#e2762c}
  .if-blk.cat-if-flow{border-left-color:#54700B}
  .if-blk.running{box-shadow:0 0 0 2px var(--copper)}
  .if-blk.st-invalid{border-color:#e8b6a6}
  .if-blk.st-changed{border-color:#e8cf9a}

  .if-top{display:flex;align-items:center;gap:7px;padding:8px 9px 0}
  .if-ic{font-size:13px;line-height:1;flex:none}
  .if-name{
    font-family:var(--font-display);font-size:11px;font-weight:600;letter-spacing:.09em;
    text-transform:uppercase;color:var(--ink-soft);
  }
  .if-kind{font-size:10.5px;color:var(--ink-faint)}
  .if-i,.if-x{
    border:0;background:var(--line-soft);color:var(--ink-soft);border-radius:5px;
    width:19px;height:19px;font-size:11px;cursor:pointer;line-height:1;flex:none;
  }
  .if-i{margin-left:auto}
  .if-i:hover,.if-x:hover{background:var(--line);color:var(--ink)}

  .if-say{
    display:flex;align-items:center;flex-wrap:wrap;gap:5px 6px;padding:6px 10px 9px;
    font-size:13px;line-height:1.7;color:var(--ink);
  }
  .if-slot{
    border:1px solid var(--line);background:#fff;color:var(--ink);border-radius:7px;
    padding:2px 9px;font-family:var(--font-ui);font-size:12.5px;font-weight:600;cursor:pointer;
    max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .if-slot:after{content:' \25BE';font-weight:400;opacity:.5}
  .if-slot:hover{border-color:var(--copper);background:#F3FAFC}
  .if-slot.empty{
    border-style:dashed;border-color:var(--copper);background:#fff6ec;
    color:var(--copper-deep);font-weight:400;font-style:italic;
  }
  .if-state{
    display:flex;align-items:center;gap:6px;flex-wrap:wrap;
    padding:6px 10px;font-size:11.5px;line-height:1.5;
    border-top:1px solid var(--line-soft);background:var(--panel-2);color:var(--ink-soft);
  }
  .if-state .sm{font-weight:700;flex:none}
  .if-state.ok{background:#f1f9f3;color:#1c6b40}
  .if-state.bad{background:#fbe9e4;color:#a5381c}
  .if-state.warn{background:#fcf1dd;color:#8a5a13}
  .if-state i{font-style:normal;opacity:.9}
  .if-fix{
    border:1px solid currentColor;background:rgba(255,255,255,.6);color:inherit;border-radius:6px;
    padding:2px 8px;font-family:var(--font-ui);font-size:11px;cursor:pointer;
  }
  .if-fix:hover{background:#fff}
  .if-body-slot{
    background:var(--panel-2);margin:0 8px 8px;padding:8px;border-radius:9px;
    display:flex;flex-direction:column;gap:7px;border:1px dashed var(--line);
  }

  /* ---- next step suggestions ---- */
  .if-next{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:11px 12px}
  .if-next h5{
    margin:0 0 8px;font-family:var(--font-display);font-size:12.5px;font-weight:600;line-height:1.4;
  }
  .if-next .if-do{display:flex;flex-direction:column;gap:6px}

  /* ---- status bar ---- */
  .if-status{
    flex:0 0 auto;border-top:1px solid var(--line);background:var(--panel);padding:9px 13px 10px;
  }
  .if-status .st-t{
    font-family:var(--font-display);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-faint);margin-bottom:6px;
  }
  .if-counts{display:flex;flex-wrap:wrap;gap:5px}
  .if-counts span{
    background:var(--line-soft);border-radius:999px;padding:3px 9px;font-size:11.5px;color:var(--ink-soft);
  }
  .if-counts span b{font-weight:600;color:var(--ink)}
  .if-verdict{
    margin-top:7px;display:flex;align-items:center;gap:6px;font-size:12px;font-weight:600;line-height:1.45;
  }
  .if-verdict.ok{color:#1c6b40}
  .if-verdict.no{color:#8a5a13}

  /* ---- the block picker: intention first, cards not command names ---- */
  .if-cards{display:flex;flex-direction:column;gap:8px}
  .if-card{
    display:flex;align-items:flex-start;gap:11px;width:100%;text-align:left;cursor:pointer;
    border:1px solid var(--line);border-radius:11px;background:var(--panel);padding:11px 13px;
    font-family:var(--font-ui);color:var(--ink);
  }
  .if-card:hover{border-color:var(--copper);background:#F3FAFC}
  .if-card .c-ic{font-size:19px;line-height:1.15;flex:none;width:24px;text-align:center}
  .if-card b{display:block;font-size:13.5px;font-weight:600;line-height:1.35}
  .if-card span{display:block;font-size:11.5px;color:var(--ink-soft);line-height:1.5;margin-top:2px}
  .if-more{
    border:0;background:none;padding:6px 2px;color:var(--ink-soft);cursor:pointer;
    font-family:var(--font-ui);font-size:12px;text-align:left;
  }
  .if-more:hover{color:var(--copper-deep)}
  .if-sect{
    font-family:var(--font-display);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-faint);margin:12px 0 7px;
  }
  .if-sect:first-child{margin-top:0}
  .if-opts{display:flex;flex-wrap:wrap;gap:6px}
  .if-opt{
    border:1px solid var(--line);background:var(--panel);border-radius:9px;padding:7px 12px;
    font-family:var(--font-ui);font-size:12.5px;color:var(--ink);cursor:pointer;
  }
  .if-opt:hover{border-color:var(--copper);background:#F3FAFC}
  .if-legend{
    display:flex;gap:9px;flex-wrap:wrap;margin-top:10px;font-size:11px;color:var(--ink-soft);line-height:1.5;
  }
  .if-legend div{flex:1;min-width:150px;background:var(--panel-2);border-radius:9px;padding:8px 10px}
  .if-legend b{display:block;color:var(--ink);font-size:12px}

  .if-stages{display:flex;flex-direction:column;gap:7px;margin-top:10px}
  .if-stages div{
    background:var(--panel-2);border-radius:9px;padding:8px 11px;font-size:11.5px;
    line-height:1.5;color:var(--ink-soft);
  }
  .if-stages b{display:block;color:var(--ink);font-size:12.5px;font-family:var(--font-display);font-weight:600}

  /* ---------- build phases ---------- */
  .phase-head{
    display:flex;align-items:center;gap:9px;padding:13px 14px 8px;
    border-top:1px solid var(--line);background:var(--panel);
  }
  .phase-head:first-child{border-top:0}
  .phase-head .ph-n{
    width:22px;height:22px;border-radius:50%;flex:none;display:grid;place-items:center;
    background:var(--line-soft);color:var(--ink-soft);font-size:11.5px;font-weight:700;
  }
  .phase-head.on .ph-n{background:var(--copper);color:#fff}
  .phase-head.done .ph-n{background:var(--live);color:#fff}
  .phase-head .ph-t{
    font-family:var(--font-display);font-size:12px;font-weight:600;letter-spacing:.06em;
    text-transform:uppercase;color:var(--ink-soft);line-height:1.35;
  }
  .phase-head.on .ph-t{color:var(--copper-deep)}
  .phase-head .ph-s{
    display:block;font-family:var(--font-ui);font-size:11px;font-weight:400;
    letter-spacing:0;text-transform:none;color:var(--ink-faint);
  }
  .assembly-check{
    display:block;margin-top:8px;padding:9px 11px;border-radius:9px;
    background:var(--panel);border:1px solid var(--line-soft);
  }
  .ac-row{
    display:flex;align-items:center;gap:7px;font-size:12px;line-height:1.7;
    color:var(--ink-faint);font-weight:400;
  }
  .ac-row.ok{color:var(--ink)}
  .ac-mark{
    width:15px;text-align:center;font-weight:700;color:var(--line);flex:none;
  }
  .ac-row.ok .ac-mark{color:var(--live)}

  /* ---------- guided steps ---------- */
  .steps-head{padding:14px 14px 10px;border-bottom:1px solid var(--line-soft)}
  .steps-head h3{margin:0 0 3px;font-family:var(--font-display);font-size:15px}
  .steps-head .meta{font-size:11px;color:var(--ink-soft);display:flex;gap:8px;flex-wrap:wrap}
  .pill{
    display:inline-block;padding:2px 8px;border-radius:999px;background:var(--line-soft);
    font-size:10.5px;color:var(--ink-soft);
  }
  .pill.g1{background:#e3f2e8;color:#1c6b40}
  .pill.g2{background:#fcf1dd;color:#8a5a13}
  .pill.g3{background:#fbe9e4;color:#a5381c}
  .progbar{height:6px;border-radius:3px;background:var(--line-soft);overflow:hidden;margin-top:9px}
  .progbar i{display:block;height:100%;background:var(--live);transition:width .3s}
  .step{
    display:flex;gap:9px;padding:10px 14px;border-bottom:1px solid var(--line-soft);
    font-size:12.5px;line-height:1.5;
  }
  .step .num{
    width:19px;height:19px;flex:none;border-radius:50%;background:var(--line-soft);color:var(--ink-soft);
    display:grid;place-items:center;font-size:10.5px;font-weight:600;margin-top:1px;
  }
  .step.done{color:var(--ink-soft)}
  .step.done .num{background:var(--live);color:#fff}
  .step.now{background:#fff}
  .step.now .num{background:var(--copper);color:#fff}
  .step.now .txt{font-weight:500;color:var(--ink)}
  .step .txt{flex:1}
  .step .sub{display:block;margin-top:3px;font-size:11.5px;color:var(--ink-soft)}
  .step{cursor:pointer}
  .step .why{
    display:block;margin-top:7px;padding:8px 10px;border-radius:8px;
    background:var(--panel);border:1px solid var(--line-soft);
    font-size:12px;line-height:1.6;color:var(--ink-soft);font-weight:400;
  }
  .step.now .why{background:#fbf6f1;border-color:#ecd9c8}
  .step .more{
    display:block;margin-top:3px;font-size:11px;color:var(--copper);opacity:.85;
  }
  .step:hover .more{text-decoration:underline}
  .demo-btn{margin-top:8px}
  .joint-shaft-line{
    fill:none;stroke:var(--copper);stroke-width:3.5;stroke-linecap:round;opacity:.34;
  }
  .joint-collar{
    fill:none;stroke:var(--copper);stroke-width:2;opacity:.8;
  }
  .demo-glow{
    fill:none;stroke:var(--copper);stroke-width:2.5;pointer-events:none;
    animation:demoPulse 2s ease-out forwards;
  }
  @keyframes demoPulse{
    0%{opacity:0;stroke-width:6} 12%{opacity:1} 70%{opacity:.85;stroke-width:2.5} 100%{opacity:0}
  }
  .demo-flash{animation:wireFlash 1.4s ease-out}
  @keyframes wireFlash{ 0%,100%{stroke-width:3.4} 25%{stroke-width:8} 55%{stroke-width:3.4} }
  @media (prefers-reduced-motion:reduce){
    .demo-glow{animation:none;opacity:.9}
    .demo-flash{animation:none}
  }
  .step-actions{padding:12px 14px;display:flex;flex-direction:column;gap:8px}
  .btn-row{display:flex;gap:8px}
  .btn{
    height:32px;padding:0 12px;border:1px solid var(--line);border-radius:8px;background:var(--panel-2);
    font-family:var(--font-ui);font-size:12.5px;font-weight:500;color:var(--ink);cursor:pointer;
    display:inline-flex;align-items:center;justify-content:center;gap:6px;
  }
  .btn:hover{border-color:var(--copper);color:var(--copper-deep)}
  /* White on the vivid accent is 3.46:1 — under the AA floor at button size.
     A filled button carries a LABEL, so it takes the ink shade; the vivid one
     stays for borders, bars and glows. Same rule as .btn-new and #btn-sim. */
  .btn.solid{background:var(--accent-deep);border-color:var(--accent-deep);color:#fff}
  .btn.solid:hover{background:var(--accent-dark);border-color:var(--accent-dark);color:#fff}
  .btn.go{background:var(--accent-deep);border-color:var(--accent-deep);color:#fff}
  .btn.go:hover{background:var(--accent-dark);border-color:var(--accent-dark);color:#fff}
  .btn.wide{width:100%}
  .btn:disabled{opacity:.45;cursor:default}
  .btn.small{height:26px;padding:0 9px;font-size:11.5px}
  .btn.big{height:42px;padding:0 20px;font-size:14px;border-radius:10px;font-weight:600}

  /* ---------- full-screen views ---------- */
  #view{
    position:fixed;inset:0;z-index:40;background:var(--paper);display:flex;flex-direction:column;
    --page-pad:22px;
  }
  #view[hidden]{display:none}
  #view-head{
    display:flex;align-items:center;height:60px;flex:none;padding:0 22px;
    background:var(--panel);border-bottom:1px solid var(--line);
    /* the header owns its own stacking context and sits above the page body,
       so nothing painted by #view-body can ever ride over it again */
    position:relative;z-index:2;box-shadow:0 1px 2px rgba(15,23,42,.04);
  }
  /* the header pads by the body's gutter PLUS the scrollbar the body reserves,
     so the two columns start and end on the same pixel at every width */
  #view-head{padding:0 calc(var(--page-pad) + var(--sbw, 0px))}
  /* the header's contents share the page's column, so the logo lines up with
     the first word of the page and the account chip with its right edge */
  #view-head .head-in{
    display:flex;align-items:center;gap:20px;width:100%;max-width:1180px;margin:0 auto;
  }
  #logo.small .mark{width:27px;height:27px}
  #logo.small .name{padding:4px 7px}
  #logo.small .name svg{height:10px}
  #logo.small .tagline{font-size:7px}
  #view-nav{display:flex;gap:2px}
  #view-nav button{
    height:32px;padding:0 12px;border:0;border-radius:8px;background:transparent;
    font-family:var(--font-ui);font-size:13px;font-weight:500;color:var(--ink-soft);cursor:pointer;
  }
  #view-nav button:hover{background:var(--line-soft);color:var(--ink)}
  #view-nav button.on{background:var(--copper-soft);color:var(--copper-deep);font-weight:600}
  /* both-edges keeps the scrollbar from stealing half its width from the
     centring, so the page column lines up with the header column exactly, and
     nothing shifts sideways between a short page and a long one */
  #view-body{
    flex:1;overflow-y:auto;padding:30px var(--page-pad) 72px;
    scrollbar-gutter:stable both-edges;
  }
  .wrap{max-width:1180px;margin:0 auto}
  .vh{font-family:var(--font-display);font-size:23px;margin:0 0 4px}
  .vsub{color:var(--ink-soft);font-size:13px;margin:0 0 20px;max-width:62ch;line-height:1.6}
  .sect{font-family:var(--font-display);font-size:12px;letter-spacing:.11em;text-transform:uppercase;
        color:var(--ink-soft);margin:26px 0 10px}
  .grid{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(258px,1fr))}
  .grid.wide{grid-template-columns:repeat(auto-fill,minmax(330px,1fr))}
  .pcard{
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;padding:14px;
    display:flex;flex-direction:column;gap:8px;cursor:pointer;text-align:left;font:inherit;color:inherit;
  }
  .pcard:hover{border-color:var(--copper);box-shadow:var(--shadow)}
  .pcard h4{margin:0;font-family:var(--font-display);font-size:14.5px}
  .pcard p{margin:0;font-size:12px;color:var(--ink-soft);line-height:1.5}
  .pcard .tags{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto;padding-top:4px}
  .pcard .done-flag{color:var(--live);font-size:11.5px;font-weight:600}
  .pcard.locked{opacity:.55}
  .pcard.primary{border-color:var(--copper);background:var(--copper-soft)}
  .pcard.primary h4{color:var(--copper-deep)}
  .pcard.primary p{color:#8a5232}
  .stat-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
  .stat{
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;padding:13px 15px;
  }
  .stat .k{font-size:11px;color:var(--ink-soft);letter-spacing:.06em;text-transform:uppercase}
  .stat .v{font-family:var(--font-display);font-size:26px;font-weight:600;line-height:1.25;
           font-variant-numeric:tabular-nums}
  .stat .sub{font-size:11.5px;color:var(--ink-soft)}
  table.data{width:100%;border-collapse:collapse;font-size:12.5px;background:var(--panel-2);
             border:1px solid var(--line);border-radius:12px;overflow:hidden}
  table.data th{
    text-align:left;font-weight:600;font-size:11px;letter-spacing:.07em;text-transform:uppercase;
    color:var(--ink-soft);padding:10px 12px;background:var(--panel);border-bottom:1px solid var(--line);
  }
  table.data td{padding:10px 12px;border-bottom:1px solid var(--line-soft);vertical-align:middle}
  table.data tr:last-child td{border-bottom:0}
  table.data td.num{text-align:right;font-variant-numeric:tabular-nums}
  .tag{
    display:inline-block;padding:2px 8px;border-radius:999px;background:var(--line-soft);
    font-size:10.5px;color:var(--ink-soft);
  }
  .badge{
    display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border-radius:999px;
    background:var(--panel-2);border:1px solid var(--line);font-size:12px;
  }
  .badge .em{font-size:15px}
  .badge.locked{opacity:.4}
  .medal{font-size:12px;font-weight:600}
  .medal.gold{color:#a8801a} .medal.silver{color:#6c757d} .medal.bronze{color:#96552c}
  .levelbar{display:flex;gap:6px;margin:10px 0 4px}
  .levelbar i{flex:1;height:7px;border-radius:4px;background:var(--line-soft)}
  .levelbar i.on{background:var(--copper)}
  .field{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
  .field label{font-size:12px;color:var(--ink-soft)}
  .field input,.field select,.field textarea{
    height:34px;border:1px solid var(--line);border-radius:8px;background:var(--panel-2);
    padding:0 10px;font-family:var(--font-ui);font-size:13px;color:var(--ink);
  }
  .field textarea{height:74px;padding:8px 10px;resize:vertical}
  .field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--copper)}
  .joincode{
    font-family:var(--font-mono);font-size:19px;letter-spacing:.16em;background:var(--copper-soft);
    color:var(--copper-deep);padding:7px 13px;border-radius:9px;display:inline-block;font-weight:500;
  }
  .row-between{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .bar{height:8px;border-radius:4px;background:var(--line-soft);overflow:hidden;min-width:80px}
  .bar i{display:block;height:100%;background:var(--copper)}
  .bar.good i{background:var(--live)}
  .muted{color:var(--ink-soft)}
  .mini{font-size:11.5px}
  ul.clean{margin:6px 0 0;padding-left:17px;font-size:12.5px;line-height:1.6;color:var(--ink-soft)}
  ul.clean li{margin:2px 0}
  ol.clean{margin:6px 0 0;padding-left:19px;font-size:12.5px;line-height:1.65;color:var(--ink-soft)}

  /* =========================================================
     Page shell — the four primary experiences and everything
     that supports them. Same tokens as the workspace: warm
     paper, one copper accent, no gradients, no glass.
     ========================================================= */

  /* ---- the top bar of a page ---- */
  #view-head{gap:0}
  #view-nav{display:flex;gap:3px;align-items:center}
  #view-nav .nav-gap{width:1px;height:22px;background:var(--line);margin:0 8px}
  #view-nav button{
    height:34px;padding:0 13px;border:0;border-radius:9px;background:transparent;
    font-family:var(--font-ui);font-size:13.5px;font-weight:500;color:var(--ink-soft);cursor:pointer;
    white-space:nowrap;
  }
  #view-nav button.sec{font-size:12.5px;color:var(--ink-faint);padding:0 10px}
  #view-nav button:hover{background:var(--line-soft);color:var(--ink)}
  #view-nav button.on{background:var(--copper-soft);color:var(--copper-deep);font-weight:600}
  #view-nav button.sec.on{background:var(--line-soft);color:var(--ink)}
  #nav-more{display:none}

  /* ---- hero ---- */
  /* ============ I 4 Invent: page design tokens ============ */
  :root{
    --sb-canvas:#F4F8FA;      --sb-grid:#DDE7EE;
    --sb-ink:#0F2C4E;         --sb-ink-soft:#4A6480;
    --sb-line:#DDE7EE;        --sb-panel:#FFFFFF;
    /* The action colour is the accent cyan. White on it is about 3.2:1, so the
       vivid shade does the DECORATIVE work (bars, glows, fills) and the "ink"
       shade does anything that has to be read. Same reason each mode carries a
       darker ink alongside its colour: the base hues score 1.6–3.6:1 on fills. */
    --sb-action:var(--accent);
    --sb-action-ink:var(--accent-deep);
    --sb-action-dark:#005265;
    /* One accent per experience, read straight off the bulb's gradient in the
       logo — yellow, green, teal, cyan, blue, in that order. The five
       experiences literally are the five stops of the mark. */
    --sb-invent:#EFD808;      --sb-invent-fill:#FDF8C6;  --sb-invent-ink:#786806;
    --sb-train:#5CB85C;       --sb-train-fill:#E2F4E0;   --sb-train-ink:#2F7A31;
    --sb-chal:#22B08A;        --sb-chal-fill:#D5F2E9;    --sb-chal-ink:#0F6B58;
    --sb-explore:#12B0B5;     --sb-explore-fill:#D2F1F3; --sb-explore-ink:#08696D;
    --sb-code:#0092B8;        --sb-code-fill:#D5EDF6;    --sb-code-ink:#046A87;
  }

  /* the canvas the page layer sits on: off-white, with a circuit grid */
  /* The wash that keeps the grid from fighting the text is a BACKGROUND
     LAYER, not a pseudo-element. As an absolutely positioned ::before it
     resolved against #view (the only positioned ancestor) and covered the
     header as well — a white veil over the whole page layer. A background
     is clipped to its own box and can never do that. */
  #view-body{
    background-color:var(--sb-canvas);
    background-image:
      radial-gradient(ellipse 130% 70% at 50% 0, rgba(248,250,252,.55), rgba(248,250,252,.93) 62%),
      linear-gradient(var(--sb-grid) 1px, transparent 1px),
      linear-gradient(90deg, var(--sb-grid) 1px, transparent 1px);
    background-size:100% 100%, 28px 28px, 28px 28px;
    background-position:0 0, -1px -1px, -1px -1px;
    background-repeat:no-repeat, repeat, repeat;
    background-attachment:fixed, scroll, scroll;
  }
  #view-body .wrap{position:relative}

  #view-head .head-actions{display:flex;align-items:center;gap:9px;margin-left:auto}
  .btn-new{
    display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 14px;
    border:0;border-radius:9px;background:var(--sb-action-ink);color:#fff;cursor:pointer;
    font-family:var(--font-ui);font-size:13px;font-weight:600;
    box-shadow:0 1px 2px rgba(15,23,42,.12);
    transition:background .14s ease, transform .14s ease, box-shadow .14s ease;
  }
  .btn-new:hover{background:var(--sb-action-dark);transform:translateY(-1px);
                 box-shadow:0 4px 12px rgba(234,88,12,.32)}
  .btn-new:focus-visible{outline:2px solid var(--sb-action-ink);outline-offset:2px}
  .btn-new svg{flex:none}
  /* There is no ✕ in the header. The way back to the workspace is the account
     menu's "Back to the canvas", and the home page's Resume strip, which names
     what you would be going back TO — a bare cross never did. */

  /* ---- header: search, My Stuff, account ----
     The bar reads left to right as: who we are · where to go · find something ·
     your own things · the one action · you. The nav shrank to three because a
     six-item bar made every destination look equally important. */

  #head-search{position:relative;display:flex;align-items:center;flex:0 1 240px;min-width:0}
  #head-search .hs-ic{
    position:absolute;left:10px;color:var(--ink-faint);pointer-events:none;
  }
  #hs-q{
    width:100%;height:34px;border:1px solid var(--line);border-radius:9px;
    background:var(--panel-2);padding:0 10px 0 31px;
    font-family:var(--font-ui);font-size:13px;color:var(--ink);
  }
  #hs-q::placeholder{color:var(--ink-faint)}
  #hs-q:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
  #hs-q:focus + #hs-results{border-color:var(--accent)}
  /* the native clear affordance duplicates Esc and sits on our own padding */
  #hs-q::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
  #hs-results{
    position:absolute;top:calc(100% + 6px);left:0;width:min(380px,74vw);z-index:20;
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;
    box-shadow:var(--shadow-pop);padding:5px;max-height:min(62vh,430px);overflow-y:auto;
  }
  #hs-results[hidden]{display:none}
  .hs-group{
    font-size:9.5px;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-faint);
    font-weight:700;padding:8px 9px 4px;
  }
  .hs-item{
    display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;
    background:none;border:0;border-radius:8px;padding:7px 9px;cursor:pointer;color:var(--ink);
  }
  .hs-item:hover,.hs-item.on{background:var(--accent-soft)}
  .hs-item .hs-em{
    flex:none;width:26px;height:26px;border-radius:7px;display:grid;place-items:center;
    background:var(--line-soft);font-size:13px;
  }
  .hs-item .hs-em svg{width:19px;height:19px}
  .hs-t{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
  .hs-t b{font-size:12.5px;font-weight:600;line-height:1.3;white-space:nowrap;
          overflow:hidden;text-overflow:ellipsis}
  .hs-t span{font-size:11px;color:var(--ink-soft);line-height:1.3;white-space:nowrap;
             overflow:hidden;text-overflow:ellipsis}
  .hs-empty{padding:16px 11px;font-size:12.5px;color:var(--ink-soft);text-align:center}

  /* ---- a header dropdown (My Stuff, account) ---- */
  .hmenu{position:relative;flex:none}
  .hmenu-btn{
    display:inline-flex;align-items:center;gap:5px;height:34px;padding:0 11px;
    border:1px solid transparent;border-radius:9px;background:transparent;cursor:pointer;
    font-family:var(--font-ui);font-size:13px;font-weight:500;color:var(--ink-soft);
    white-space:nowrap;
  }
  .hmenu-btn:hover{background:var(--line-soft);color:var(--ink)}
  .hmenu-btn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
  .hmenu-btn .caret{font-size:9px;opacity:.75;transition:transform .16s ease}
  .hmenu-btn[aria-expanded="true"]{background:var(--accent-soft);color:var(--accent-deep)}
  .hmenu-btn[aria-expanded="true"] .caret{transform:rotate(180deg)}
  /* the button reads as active while one of the pages it holds is the one open */
  .hmenu-btn.holds-on{color:var(--accent-deep);font-weight:600}
  .hmenu-pop{
    position:absolute;top:calc(100% + 6px);left:0;z-index:20;min-width:212px;
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;
    box-shadow:var(--shadow-pop);padding:5px;
  }
  .hmenu-pop.right{left:auto;right:0}
  .hmenu-pop[hidden]{display:none}
  .hmenu-item{
    display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;
    background:none;border:0;border-radius:8px;padding:8px 9px;cursor:pointer;
    font-size:13px;color:var(--ink);
  }
  .hmenu-item:hover{background:var(--accent-soft)}
  .hmenu-item.on{background:var(--accent-soft);color:var(--accent-deep);font-weight:600}
  .hmenu-item .mi-ic{flex:none;width:17px;display:grid;place-items:center;color:var(--ink-faint)}
  .hmenu-item.on .mi-ic{color:var(--accent-deep)}
  .hmenu-item small{display:block;font-size:11px;color:var(--ink-soft);font-weight:400}
  .hmenu-note{
    padding:9px 10px;font-size:11.5px;line-height:1.5;color:var(--ink-soft);
  }
  .hmenu-note b{display:block;color:var(--ink);font-size:12.5px;margin-bottom:2px}
  .hmenu-sep{height:1px;background:var(--line-soft);margin:4px 6px}

  .avatar-btn{padding:0 7px 0 4px}
  .avatar{
    width:28px;height:28px;border-radius:999px;display:grid;place-items:center;flex:none;
    background:var(--brand-navy);color:#fff;
  }

  /* Below 1100px the header runs out of room before the page does. The tagline
     goes first, then the search collapses to its icon, then the labels. */
  @media (max-width:1180px){
    #view-head .head-in{gap:12px}
    #head-search{flex:0 1 190px}
  }
  @media (max-width:1000px){
    #head-search{flex:0 0 34px}
    #hs-q{padding-left:31px;padding-right:0;cursor:pointer}
    #hs-q:focus{position:absolute;left:0;width:300px;max-width:60vw;cursor:text;z-index:21}
  }
  @media (max-width:820px){
    #view-nav button{padding:0 8px;font-size:12.5px}
    #mystuff-btn{padding:0 8px}
  }

  /* ---- the finish popup: one circuit, two readings ---- */
  .bbpair{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:14px 0 4px}
  .bbpair.one{grid-template-columns:1fr}
  .bbfig{margin:0;display:flex;flex-direction:column;gap:8px;min-width:0}
  .bbfig-art{
    background:#fbfbf8;border:1px solid var(--line);border-radius:11px;
    padding:8px;height:210px;display:grid;place-items:center;overflow:hidden;
  }
  .bbfig-art svg{width:100%;height:100%;display:block}
  .bbfig figcaption b{display:block;font-size:12.5px;font-weight:600;line-height:1.35}
  .bbfig figcaption span{display:block;font-size:11.5px;color:var(--ink-soft);margin-top:2px;line-height:1.45}
  .bbnote{
    margin:12px 0 0;font-size:12.5px;line-height:1.6;color:var(--ink-soft);
    background:var(--panel-2);border:1px solid var(--line-soft);border-radius:10px;padding:11px 13px;
  }
  @media (max-width: 720px){
    .bbpair{grid-template-columns:1fr}
    .bbfig-art{height:180px}
  }

  /* ---- page modules ----
     Every block below the hero is its own panel on the page: one width, one
     rhythm, one edge to line up against. Modules stay separate things. */
  .mod{
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:16px;
    padding:17px 20px 20px;margin-top:18px;
    box-shadow:0 1px 2px rgba(15,23,42,.05);
  }
  .mod .rowcard,.mod .resume,.mod .tcard,.mod .kpi,.mod .tcard .t-art{
    background:var(--sb-canvas);border-color:var(--sb-line);
  }
  .mod .tcard .t-art{background:var(--sb-panel);border-bottom-color:var(--sb-line)}
  .mod .tcard:hover,.mod .rowcard:hover{border-color:var(--sb-action-ink)}
  .mod > .emptyx{background:transparent;margin:0;border-color:var(--sb-line)}
  .mod .sect-row h2{font-size:15.5px}
  /* the rule under the title is what makes a module read as a titled block */
  .mod > .sect-row:first-child{
    margin:0 0 16px;padding-bottom:12px;border-bottom:1px solid var(--sb-line);
  }
  @media (max-width: 700px){ .mod{padding:15px 14px 16px;border-radius:14px} }

  .hero{padding:14px 0 6px}
  /* the row of experience cards is the page's own module, spaced like one */
  .hub{margin-top:22px}
  .hero h1{
    margin:0;font-family:var(--font-display);font-size:38px;font-weight:700;
    letter-spacing:-.01em;line-height:1.1;
  }
  .hero .kicker{
    font-family:var(--font-display);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
    color:var(--copper-deep);margin-bottom:8px;font-weight:600;
  }
  .hero p{
    margin:10px 0 0;font-size:15px;line-height:1.6;color:var(--ink-soft);max-width:56ch;
  }
  .hero .hero-cta{display:flex;gap:9px;flex-wrap:wrap;margin-top:18px}

  /* ---- the four primary experiences ---- */
  .hub{display:grid;gap:16px;grid-template-columns:repeat(2,1fr);margin-top:26px;align-items:stretch}
  .hub-card{
    --mode:var(--sb-action); --mode-fill:var(--copper-soft); --mode-ink:var(--sb-action-ink);
    position:relative;display:flex;flex-direction:column;gap:8px;text-align:left;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:16px;
    padding:24px 22px 20px;cursor:pointer;font:inherit;color:var(--sb-ink);
    overflow:hidden;isolation:isolate;
    box-shadow:0 1px 2px rgba(15,23,42,.05);
    transition:box-shadow .18s ease, transform .18s ease, border-color .18s ease;
  }
  /* the mode's colour, as a bar across the top */
  .hub-card::before{
    content:'';position:absolute;top:0;left:0;right:0;height:3px;background:var(--mode);
  }
  .hub-card.invent {--mode:var(--sb-invent);  --mode-fill:var(--sb-invent-fill);  --mode-ink:var(--sb-invent-ink)}
  .hub-card.train  {--mode:var(--sb-train);   --mode-fill:var(--sb-train-fill);   --mode-ink:var(--sb-train-ink)}
  .hub-card.chal   {--mode:var(--sb-chal);    --mode-fill:var(--sb-chal-fill);    --mode-ink:var(--sb-chal-ink)}
  .hub-card.explore{--mode:var(--sb-explore); --mode-fill:var(--sb-explore-fill); --mode-ink:var(--sb-explore-ink)}
  .hub-card.code   {--mode:var(--sb-code);    --mode-fill:var(--sb-code-fill);    --mode-ink:var(--sb-code-ink)}

  /* ================= Code Lab — the fifth experience ================= */
  /* the wide card sits under the four, as the thing you do alongside them */
  .hub-card.span2{grid-column:1 / -1}
  .hub-card.span2 .hc-body{max-width:64ch}

  .cl-strip{
    display:flex;align-items:center;gap:14px;margin-top:20px;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:14px;
    padding:14px 16px;
  }
  .cl-strip-t{display:flex;flex-direction:column;gap:2px;min-width:0}
  .cl-strip-t b{font-family:var(--font-display);font-size:14.5px}
  .cl-strip-t span{font-size:12.5px;color:var(--sb-ink-soft)}
  .cl-bar{flex:1;min-width:70px;height:7px;border-radius:99px;background:var(--sb-line);overflow:hidden}
  .cl-bar i{display:block;height:100%;background:var(--sb-code);border-radius:99px;transition:width .3s ease}
  .cl-pct{font-family:var(--font-mono);font-size:12px;color:var(--sb-code-ink);font-weight:600}

  .cl-list{display:grid;gap:10px;margin-top:6px}
  .cl-card{
    display:flex;align-items:flex-start;gap:13px;text-align:left;font:inherit;color:var(--sb-ink);
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:13px;
    padding:14px 15px;cursor:pointer;
    transition:border-color .15s ease, box-shadow .15s ease, transform .15s ease;
  }
  .cl-card:hover{border-color:var(--sb-code);box-shadow:0 4px 14px rgba(244,63,94,.13);transform:translateY(-1px)}
  .cl-card:focus-visible{outline:2px solid var(--sb-code);outline-offset:2px}
  .cl-n{
    flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
    background:var(--sb-code-fill);color:var(--sb-code-ink);
    font-family:var(--font-display);font-size:13.5px;font-weight:700;
  }
  .cl-card.done .cl-n{background:var(--sb-chal-fill);color:var(--sb-chal-ink)}
  .cl-body{display:flex;flex-direction:column;gap:3px;min-width:0;flex:1}
  .cl-body b{font-family:var(--font-display);font-size:14.5px;line-height:1.3}
  .cl-idea{font-size:13px;line-height:1.5;color:var(--sb-ink-soft)}
  .cl-meta{font-size:11.5px;color:var(--sb-ink-soft);opacity:.85}
  .cl-go{flex:none;color:var(--sb-code);font-size:15px;align-self:center;transition:transform .15s ease}
  .cl-card:hover .cl-go{transform:translateX(3px)}

  /* ---- one lesson ---- */
  .cl-back{
    background:none;border:0;font:inherit;font-size:12.5px;color:var(--sb-ink-soft);
    cursor:pointer;padding:2px 0;margin-bottom:10px;
  }
  .cl-back:hover{color:var(--sb-code-ink)}
  .cl-head{padding:2px 0 4px}
  .cl-crumb{
    font-family:var(--font-display);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--sb-code-ink);font-weight:600;
  }
  .cl-head h1{margin:8px 0 0;font-family:var(--font-display);font-size:31px;line-height:1.15;letter-spacing:-.01em}
  .cl-big{margin:10px 0 0;font-size:16px;line-height:1.55;color:var(--sb-ink);max-width:60ch;font-weight:600}
  .cl-needs{
    display:inline-block;margin-top:12px;font-size:11.5px;font-family:var(--font-mono);
    background:var(--sb-code-fill);color:var(--sb-code-ink);border-radius:99px;padding:4px 11px;
  }

  .cl-sect{
    margin-top:20px;background:var(--sb-panel);border:1px solid var(--sb-line);
    border-radius:15px;padding:17px 18px;
  }
  .cl-sect h3{
    margin:0 0 11px;font-family:var(--font-display);font-size:14px;
    display:flex;align-items:center;gap:8px;
  }
  .cl-ic{font-size:15px}
  .cl-story{margin:0;font-size:14.5px;line-height:1.7;color:var(--sb-ink);max-width:66ch}
  .cl-note{margin:0 0 10px;font-size:12.5px;color:var(--sb-ink-soft)}

  .cl-codewrap{border:1px solid #24303f;border-radius:12px;overflow:hidden;background:#0f1720}
  .cl-codebar{
    display:flex;align-items:center;gap:9px;padding:8px 10px;background:#16212e;
    border-bottom:1px solid #24303f;flex-wrap:wrap;
  }
  .cl-file{font-family:var(--font-mono);font-size:11px;color:#8fa3b8}
  .cl-codeacts{margin-left:auto;display:flex;gap:7px}
  pre.cl-code{
    margin:0;padding:14px 15px;overflow-x:auto;background:#0f1720;color:#dbe6f0;
    font-family:var(--font-mono);font-size:12.5px;line-height:1.75;white-space:pre;
  }
  pre.cl-code.small{padding:10px 12px;font-size:12px;border-radius:10px}
  pre.cl-code .c-kw{color:#7dd3fc}
  pre.cl-code .c-num{color:#fbbf24}
  pre.cl-code .c-str{color:#86efac}
  pre.cl-code .c-note{color:#7d8ea0;font-style:italic}

  /* a lesson's blocks: the real block markup, made unclickable */
  .cl-blockwrap{border:1px solid var(--sb-line);border-radius:12px;overflow:hidden;background:var(--paper)}
  .cl-blockbar{
    display:flex;align-items:center;gap:9px;padding:8px 10px;background:var(--sb-panel);
    border-bottom:1px solid var(--sb-line);flex-wrap:wrap;
  }
  .cl-blockbar .cl-file{color:var(--sb-ink-soft)}
  .cl-blocks{padding:12px;display:flex;flex-direction:column;gap:12px}
  .cl-blocks .stack{flex:0 0 auto}
  .cl-blocks .bfld{background:#fff;color:var(--ink);-webkit-text-fill-color:var(--ink);opacity:1}
  .cl-blocks .grip{cursor:default}
  .cl-pair{display:grid;gap:10px;grid-template-columns:1fr 1fr;align-items:start}
  @media (max-width:760px){ .cl-pair{grid-template-columns:1fr} }
  .cl-read{display:grid;gap:8px}
  .cl-row{
    display:grid;grid-template-columns:minmax(120px,34%) 1fr;gap:12px;align-items:baseline;
    padding:9px 11px;border-radius:10px;background:var(--sb-canvas);border:1px solid var(--sb-line);
  }
  .cl-row code{
    font-family:var(--font-mono);font-size:12px;color:var(--sb-code-ink);
    word-break:break-word;
  }
  .cl-row span{font-size:13px;line-height:1.55;color:var(--sb-ink-soft)}

  ol.cl-try{margin:0;padding-left:20px;display:grid;gap:8px}
  ol.cl-try li{font-size:13.5px;line-height:1.6;color:var(--sb-ink)}

  .cl-q{margin:0 0 11px;font-size:14px;font-weight:600;line-height:1.5}
  .cl-opts{display:grid;gap:8px}
  .cl-opt{
    text-align:left;font:inherit;font-size:13.5px;color:var(--sb-ink);cursor:pointer;
    background:var(--sb-canvas);border:1px solid var(--sb-line);border-radius:10px;padding:11px 13px;
    transition:border-color .14s ease, background .14s ease;
  }
  .cl-opt:hover{border-color:var(--sb-code)}
  .cl-opt.right{background:var(--sb-chal-fill);border-color:var(--sb-chal);color:var(--sb-chal-ink);font-weight:600}
  .cl-opt.wrong{background:#FEE2E2;border-color:#F87171;color:#B91C1C}
  .cl-why{
    margin-top:11px;font-size:13px;line-height:1.6;padding:10px 12px;border-radius:10px;
    background:var(--sb-code-fill);color:var(--sb-code-ink);
  }
  .cl-why.ok{background:var(--sb-chal-fill);color:var(--sb-chal-ink)}

  .cl-words{display:grid;gap:9px;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));margin-top:4px}
  .cl-words.tight{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
  .cl-word{
    display:flex;flex-direction:column;gap:4px;text-align:left;font:inherit;cursor:pointer;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:11px;padding:11px 12px;
    transition:border-color .14s ease;
  }
  .cl-word:hover{border-color:var(--sb-code)}
  .cl-word.plain{cursor:default}
  .cl-word code{font-family:var(--font-mono);font-size:12.5px;color:var(--sb-code-ink);font-weight:600}
  .cl-word span{font-size:12px;line-height:1.5;color:var(--sb-ink-soft)}

  .cl-tmpls{display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(255px,1fr));margin-top:4px}
  .cl-tmpl{
    display:flex;flex-direction:column;gap:10px;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:14px;padding:14px 15px;
  }
  .cl-tmpl-h{display:flex;gap:11px;align-items:flex-start}
  .cl-tmpl-t{display:flex;flex-direction:column;gap:3px;min-width:0}
  .cl-tmpl-t b{font-family:var(--font-display);font-size:14px;line-height:1.3}
  .cl-tmpl-t span{font-size:12.5px;line-height:1.5;color:var(--sb-ink-soft)}
  .cl-tmpl-tags{display:flex;flex-wrap:wrap;gap:5px}
  .cl-tmpl-acts{display:flex;gap:7px;margin-top:auto;flex-wrap:wrap}

  .cl-foot{
    display:flex;gap:10px;align-items:center;flex-wrap:wrap;
    margin:22px 0 8px;padding-top:16px;border-top:1px solid var(--sb-line);
  }
  .cl-foot .btn.solid.big{margin-left:auto}

  @media (max-width:620px){
    .cl-row{grid-template-columns:1fr;gap:4px}
    .cl-strip{flex-wrap:wrap}
    .cl-bar{order:3;flex-basis:100%}
    .cl-head h1{font-size:25px}
    .cl-foot .btn.solid.big{margin-left:0;width:100%;justify-content:center}
  }


  .hub-card:hover{
    transform:translateY(-2px);border-color:var(--mode-ink);
    box-shadow:0 10px 24px rgba(15,23,42,.10), 0 2px 6px rgba(15,23,42,.06);
  }
  .hub-card:focus-visible{outline:2px solid var(--mode);outline-offset:3px}
  .hub-card .hc-ic{
    width:48px;height:48px;border-radius:13px;display:grid;place-items:center;
    background:var(--mode-fill);color:var(--mode-ink);margin-bottom:6px;flex:none;
    transition:transform .18s ease;
  }
  .hub-card:hover .hc-ic{transform:scale(1.06) rotate(-2deg)}
  .hub-card h3{
    margin:0;font-family:var(--font-display);font-size:21px;font-weight:700;
    letter-spacing:.01em;color:var(--sb-ink);
  }
  .hub-card p{margin:0;font-size:13.5px;line-height:1.55;color:var(--sb-ink-soft)}
  /* the metadata pill */
  .hub-card .hc-pill{
    align-self:flex-start;margin-top:2px;padding:3px 9px;border-radius:999px;
    background:var(--mode-fill);color:var(--mode-ink);
    font-size:11.5px;font-weight:600;letter-spacing:.01em;
    border:1px solid var(--mode);
  }
  .hub-card .hc-meta{
    margin-top:12px;padding-top:12px;border-top:1px solid var(--sb-line);
    display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--sb-ink-soft);
    font-weight:500;
  }
  .hub-card .hc-go{
    margin-left:auto;color:var(--mode-ink);font-weight:700;font-size:15px;
    display:inline-flex;transition:transform .18s ease;
  }
  .hub-card:hover .hc-go{transform:translateX(4px)}
  @media (prefers-reduced-motion: reduce){
    .hub-card,.hub-card .hc-ic,.hub-card .hc-go,.btn-new{transition:none}
    .hub-card:hover{transform:none}
    .hub-card:hover .hc-ic{transform:none}
    .hub-card:hover .hc-go{transform:none}
  }

  /* ---- supporting content, deliberately quieter ---- */
  .sect-row{display:flex;align-items:baseline;gap:12px;margin:34px 0 12px}
  .sect-row h2{
    margin:0;font-family:var(--font-display);font-size:16px;font-weight:600;
  }
  .sect-row .more{
    margin-left:auto;border:0;background:none;color:var(--copper-deep);cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;font-weight:500;padding:2px 4px;border-radius:6px;
  }
  .sect-row .more:hover{background:var(--copper-soft)}
  .sect-note{margin:-6px 0 12px;font-size:12.5px;color:var(--ink-soft);line-height:1.55;max-width:66ch}

  @media (max-width: 880px){
    .hub{grid-template-columns:1fr;gap:12px}
    .hub-card{padding:20px 18px 17px}
  }
  @media (max-width: 640px){
    .resume{flex-wrap:wrap}
    .resume .r-prev{order:1}
    .resume .r-t{order:2;flex:1 1 60%}
    .resume .btn.solid{order:3;width:100%;margin-top:4px}
    #view-head .head-actions .btn-new span{display:none}
    #view-head .head-actions .btn-new{padding:0 10px}
  }

  /* the "carry on" card: a real preview of the circuit, not a folder icon */
  .resume{
    display:flex;align-items:center;gap:16px;background:var(--sb-panel);
    border:1px solid var(--sb-line);border-radius:14px;padding:14px 16px;
    box-shadow:0 1px 2px rgba(15,23,42,.05);
  }
  .resume .r-prev{
    flex:none;display:flex;align-items:center;gap:5px;padding:9px 11px;
    border-radius:11px;background:var(--sb-canvas);border:1px solid var(--sb-line);
    min-height:52px;
  }
  .resume .r-prev .pv{width:30px;height:30px;display:grid;place-items:center}
  .resume .r-prev .pv svg{width:100%;height:100%}
  /* a part drawing shrunk to 30px keeps its pin labels, which at that size are
     just noise — the readable names are the tags beside it */
  .resume .r-prev .pv svg text{display:none}
  .resume .r-prev .r-more{font-size:11px;color:var(--sb-ink-soft);font-weight:600;padding:0 2px}
  .resume .r-ic{
    width:44px;height:44px;border-radius:11px;background:var(--sb-invent-fill);
    color:var(--sb-invent-ink);display:grid;place-items:center;font-size:19px;flex:none;
  }
  .resume .r-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px}
  .resume .r-tag{
    font-size:11px;font-weight:600;color:var(--sb-ink-soft);background:var(--sb-canvas);
    border:1px solid var(--sb-line);border-radius:999px;padding:2px 8px;
  }
  .resume .r-when{color:var(--sb-ink-soft)}
  .resume .btn.solid{background:var(--sb-action-ink);border-color:var(--sb-action-ink)}
  .resume .btn.solid:hover{background:var(--sb-action-dark);border-color:var(--sb-action-dark)}
  .resume .r-t{flex:1;min-width:0}
  .resume .r-t b{display:block;font-size:14px;font-weight:600;line-height:1.35}
  .resume .r-t span{display:block;font-size:12px;color:var(--ink-soft);margin-top:2px}
  .resume .bar{width:100%;margin-top:7px}

  /* ---- cards for projects, challenges, components ---- */
  .card-grid{display:grid;gap:13px;grid-template-columns:repeat(auto-fill,minmax(276px,1fr))}
  .tcard{
    display:flex;flex-direction:column;background:var(--panel-2);border:1px solid var(--line);
    border-radius:14px;overflow:hidden;cursor:pointer;text-align:left;font:inherit;color:inherit;
    transition:border-color .14s ease, box-shadow .14s ease;
  }
  .tcard:hover{border-color:var(--copper);box-shadow:var(--shadow)}
  .tcard .t-art{
    height:92px;background:var(--panel);border-bottom:1px solid var(--line-soft);
    display:flex;align-items:center;justify-content:center;gap:12px;padding:0 14px;
  }
  .tcard .t-art svg{width:46px;height:46px;opacity:.92}
  .tcard .t-art .more-n{font-size:12px;color:var(--ink-faint)}
  .tcard .t-in{padding:13px 15px 15px;display:flex;flex-direction:column;gap:7px;flex:1}
  .tcard h4{margin:0;font-family:var(--font-display);font-size:15px;font-weight:600;line-height:1.3}
  .tcard p{margin:0;font-size:12.5px;line-height:1.5;color:var(--ink-soft)}
  .tcard .t-meta{display:flex;flex-wrap:wrap;gap:6px;align-items:center;font-size:11.5px;color:var(--ink-faint)}
  .tcard .t-skills{font-size:11.5px;color:var(--ink-soft);line-height:1.5}
  .tcard .t-foot{
    margin-top:auto;padding-top:11px;display:flex;align-items:center;gap:9px;
  }
  .tcard .t-foot .go{
    color:var(--copper-deep);font-weight:600;font-size:12.5px;margin-left:auto;
  }
  .tcard.is-done{border-color:#A9DFCD}
  .tcard.is-done .t-art{background:#EFFAF6}
  .lvlchip{
    display:inline-block;padding:2px 9px;border-radius:999px;font-size:10.5px;font-weight:600;
    letter-spacing:.03em;
  }
  .lvlchip.b1{background:var(--brand-lime-soft);color:var(--brand-lime-ink)}
  .lvlchip.b2{background:#D5F2E9;color:#0F6B58}
  .lvlchip.b3{background:#D5EDF6;color:#046A87}
  .dot-sep{color:var(--line)}

  /* ---- a compact list row (my projects, resources) ---- */
  .rowcard{
    display:flex;align-items:center;gap:14px;background:var(--panel-2);border:1px solid var(--line);
    border-radius:12px;padding:13px 15px;
  }
  .rowcard + .rowcard{margin-top:9px}
  .rowcard .rc-t{flex:1;min-width:0}
  .rowcard .rc-t b{display:block;font-size:14px;font-weight:600}
  .rowcard .rc-t span{display:block;font-size:12px;color:var(--ink-soft);margin-top:2px}
  .rowcard .rc-acts{display:flex;gap:6px;flex-wrap:wrap;flex:none}

  /* ---- components browser ---- */
  .comp-grid{display:grid;gap:9px;grid-template-columns:repeat(auto-fill,minmax(112px,1fr))}
  .comp-tile{
    background:var(--panel-2);border:1px solid var(--line);border-radius:11px;padding:11px 8px 9px;
    display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer;font:inherit;color:inherit;
  }
  .comp-tile:hover{border-color:var(--copper);box-shadow:var(--shadow)}
  .comp-tile svg{width:40px;height:40px}
  .comp-tile .cl{font-size:11.5px;color:var(--ink-soft);text-align:center;line-height:1.35}

  /* ---- empty states: never a dead end ---- */
  .emptyx{
    background:var(--panel-2);border:1px dashed var(--line);border-radius:14px;
    padding:34px 26px;text-align:center;
  }
  .emptyx .e-ic{font-size:30px;display:block;margin-bottom:10px}
  .emptyx h4{margin:0 0 5px;font-family:var(--font-display);font-size:16px;font-weight:600}
  .emptyx p{margin:0 auto 16px;font-size:13px;color:var(--ink-soft);line-height:1.6;max-width:44ch}

  /* ---- small pieces ---- */
  .kpi-row{display:grid;gap:11px;grid-template-columns:repeat(auto-fit,minmax(132px,1fr))}
  .kpi{
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;padding:13px 15px;
  }
  .kpi .k{font-size:10.5px;color:var(--ink-faint);letter-spacing:.08em;text-transform:uppercase}
  .kpi .v{
    font-family:var(--font-display);font-size:24px;font-weight:600;line-height:1.3;
    font-variant-numeric:tabular-nums;
  }
  .kpi .s{font-size:11.5px;color:var(--ink-soft)}

  /* ---- home page: split hero, 3-up hub, progress tiles with icons ---- */
  .hero-in{display:flex;align-items:center;gap:36px}
  .hero-copy{flex:1;min-width:0}
  .hero-art{flex:none;width:min(44%,430px)}
  .hero-art svg{width:100%;height:auto;display:block}
  .hero h1 .hd{color:var(--sb-action)}
  @media (max-width: 860px){ .hero-art{display:none} }

  .hub-mod .hub,.resume-mod .resume{margin-top:0}
  .hub.hub-3{grid-template-columns:repeat(3,1fr)}
  @media (max-width: 940px){ .hub.hub-3{grid-template-columns:1fr} }
  .resume-mod > .sect-row:first-child h2,
  .resume-mod .sect-row h2{
    font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--sb-action-ink);font-weight:700;
  }

  .kpi-icons .kpi{display:flex;align-items:flex-start;gap:13px}
  .kpi-icons .kpi .kt{flex:1;min-width:0}
  .kpi-ic{
    flex:none;width:44px;height:44px;border-radius:999px;display:grid;place-items:center;
  }
  .kpi-ic.i-level{background:var(--sb-invent-fill);color:var(--sb-invent-ink)}
  .kpi-ic.i-proj {background:var(--sb-train-fill); color:var(--sb-train-ink)}
  .kpi-ic.i-badge{background:var(--sb-chal-fill);  color:var(--sb-chal-ink)}
  .kpi-ic.i-chal {background:var(--sb-explore-fill);color:var(--sb-explore-ink)}
  .kpi-icons .kpi .bar{width:100%;margin-top:9px}
  .kpi-icons .kpi .bar i{background:var(--sb-train)}
  .kpi-icons .dots{display:flex;gap:6px;margin-top:10px}
  .kpi-icons .dots i{width:9px;height:9px;border-radius:999px;background:var(--sb-line);flex:none}
  .kpi-icons .dots i.on{background:var(--sb-chal)}
  @media (max-width: 720px){ .kpi-row.kpi-icons{grid-template-columns:1fr 1fr} }

  .panel-box{
    background:var(--panel-2);border:1px solid var(--line);border-radius:14px;padding:18px 20px;
  }
  .panel-box h3{margin:0 0 4px;font-family:var(--font-display);font-size:16px;font-weight:600}
  .panel-box > p{margin:0 0 14px;font-size:12.5px;color:var(--ink-soft);line-height:1.6}

  /* the journey ribbon on the Invent page */
  .journey{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px}
  .journey .j{
    display:flex;align-items:center;gap:7px;background:var(--panel);border:1px solid var(--line-soft);
    border-radius:999px;padding:6px 13px 6px 8px;font-size:12px;color:var(--ink-soft);
  }
  .journey .j i{
    width:19px;height:19px;border-radius:50%;background:var(--line-soft);color:var(--ink-faint);
    display:grid;place-items:center;font-style:normal;font-size:10.5px;font-weight:700;flex:none;
  }
  .journey .j.on{background:var(--copper-soft);border-color:var(--copper);color:var(--copper-deep);font-weight:600}
  .journey .j.on i{background:var(--copper);color:#fff}
  .journey .j.done i{background:var(--live);color:#fff}

  /* success flourish, kept brief */
  @keyframes pop-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  .pop{animation:pop-in .22s ease both}
  @media (prefers-reduced-motion:reduce){ .pop{animation:none} }

  /* ---- the engineering loop inside InventFlow ---- */
  .iv-card{border:1px solid var(--line);border-radius:12px;background:var(--panel);overflow:hidden}
  .iv-card + .iv-card{margin-top:9px}
  .iv-head{
    display:flex;align-items:center;gap:8px;padding:10px 12px;cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;font-weight:600;color:var(--ink);
    background:none;border:0;width:100%;text-align:left;
  }
  .iv-head .iv-ic{font-size:14px;flex:none}
  .iv-head .iv-sub{font-weight:400;color:var(--ink-faint);font-size:11.5px}
  .iv-head .iv-chev{margin-left:auto;color:var(--ink-faint);font-size:11px}
  .iv-head:hover{background:var(--panel-2)}
  .iv-body{padding:0 12px 12px;font-size:12px;line-height:1.6;color:var(--ink-soft)}
  .iv-card.hot{border-color:var(--copper)}
  .iv-card.hot .iv-head{color:var(--copper-deep)}

  .iv-metrics{display:grid;gap:6px;grid-template-columns:1fr 1fr}
  .iv-m{background:var(--panel-2);border:1px solid var(--line-soft);border-radius:9px;padding:7px 9px}
  .iv-m .k{font-size:10px;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-faint);line-height:1.4}
  .iv-m .v{font-family:var(--font-display);font-size:16px;font-weight:600;color:var(--ink);
           font-variant-numeric:tabular-nums;line-height:1.3}
  .iv-m .h{font-size:10.5px;color:var(--ink-faint);line-height:1.45;margin-top:2px}
  .iv-note{
    background:#fcf1dd;border-radius:8px;padding:7px 10px;font-size:11.5px;color:#8a5a13;
    line-height:1.5;margin-top:7px;
  }
  .iv-cannot{margin-top:9px;font-size:11px;color:var(--ink-faint);line-height:1.55}
  .iv-cannot b{display:block;color:var(--ink-soft);font-weight:600;margin-bottom:2px}

  .iv-pick{display:flex;flex-direction:column;gap:6px}
  .iv-opt{
    display:flex;align-items:flex-start;gap:9px;width:100%;text-align:left;cursor:pointer;
    border:1px solid var(--line);border-radius:9px;background:var(--panel-2);padding:8px 10px;
    font-family:var(--font-ui);font-size:12px;color:var(--ink);line-height:1.45;
  }
  .iv-opt:hover{border-color:var(--copper);background:#F3FAFC}
  .iv-opt .o-ic{font-size:14px;flex:none;width:18px;text-align:center}
  .iv-opt b{display:block;font-weight:600}
  .iv-opt span{display:block;color:var(--ink-soft);font-size:11px;margin-top:1px}

  .iv-mission{background:var(--copper-soft);border-color:var(--copper)}
  .iv-mission .iv-body{color:#7d4a26}
  .iv-lim{display:flex;align-items:center;gap:6px;font-size:11.5px;line-height:1.7}
  .iv-lim .lm{font-weight:700;flex:none;width:13px}
  .iv-lim.over{color:#a5381c;font-weight:600}

  .iv-protos{display:flex;flex-direction:column;gap:7px}
  .iv-proto{
    border:1px solid var(--line-soft);border-radius:9px;background:var(--panel-2);padding:8px 10px;
  }
  .iv-proto .p-t{display:flex;align-items:center;gap:7px;font-size:11.5px}
  .iv-proto .p-t b{font-family:var(--font-display);font-size:12px;font-weight:600;color:var(--ink)}
  .iv-proto .p-t .p-when{margin-left:auto;color:var(--ink-faint);font-size:10.5px}
  .iv-proto .p-ch{font-size:11px;color:var(--ink-soft);margin-top:3px;line-height:1.5}
  .iv-proto .p-ms{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
  .iv-proto .p-ms span{
    background:var(--line-soft);border-radius:999px;padding:2px 8px;font-size:10.5px;color:var(--ink-soft);
  }
  .iv-proto .p-ms b{color:var(--ink);font-weight:600}
  .iv-cmp{display:flex;flex-direction:column;gap:4px;margin-top:8px}
  .iv-cmp .c-row{display:flex;align-items:center;gap:8px;font-size:11.5px}
  .iv-cmp .c-row .c-l{flex:1;min-width:0;color:var(--ink-soft)}
  .iv-cmp .c-row .c-v{font-variant-numeric:tabular-nums;color:var(--ink)}
  .iv-cmp .c-row .c-d{font-weight:600;flex:none;min-width:66px;text-align:right}
  .iv-cmp .c-row.good .c-d{color:#1c6b40}
  .iv-cmp .c-row.bad .c-d{color:#a5381c}
  .iv-cmp .c-row.same .c-d{color:var(--ink-faint)}

  .iv-diag{border:1px solid #e8b6a6;border-radius:10px;background:#fbe9e4;padding:9px 11px;margin-top:8px}
  .iv-diag h6{margin:0 0 3px;font-family:var(--font-display);font-size:12.5px;font-weight:600;color:#a5381c}
  .iv-diag p{margin:0;font-size:11.5px;line-height:1.55;color:#8a3a22}
  .iv-diag ul{margin:5px 0 0;padding-left:16px;font-size:11.5px;line-height:1.6;color:#8a3a22}
  .iv-diag .iv-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
  .iv-hint{background:rgba(255,255,255,.7);border-radius:8px;padding:7px 9px;margin-top:7px;
           font-size:11.5px;line-height:1.55;color:#7a3419}

  .iv-idea{background:var(--panel-2);border:1px solid var(--line);border-radius:10px;padding:11px 12px}
  .iv-idea .i-t{font-size:13px;line-height:1.55;color:var(--ink);font-weight:500}
  .iv-idea .i-acts{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}

  /* ---- responsive: the four experiences stay obvious ---- */
  @media (max-width:900px){
    #view{--page-pad:18px}
    #view-body{padding:20px var(--page-pad) 60px}
    .hero h1{font-size:30px}
    .hub{gap:11px}
    .hub-card{padding:17px 17px 15px;border-radius:14px}
    .hub-card h3{font-size:18px}
    .hub-card .hc-ic{width:38px;height:38px;font-size:19px}
  }
  @media (max-width:680px){
    #view-head{height:auto;padding:7px calc(var(--page-pad) + var(--sbw, 0px))}
    #view-head .head-in{flex-wrap:wrap;gap:6px}
    #view-nav button{height:30px;padding:0 11px;font-size:13px}
    #view-nav{order:3;width:100%;overflow-x:auto;padding-bottom:2px}
    #view-nav::-webkit-scrollbar{height:0}
    #view-nav .nav-gap{display:none}
    #view-nav button.sec{display:none}
    #view-nav #nav-more{display:inline-flex}
    .hub{grid-template-columns:1fr}
    .hub-card{flex-direction:row;align-items:flex-start;gap:13px;padding:15px}
    .hub-card .hc-ic{margin-bottom:0}
    .hub-card .hc-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
    .hub-card .hc-meta{margin-top:7px;padding-top:8px}
    .hero{padding:2px 0 0}
    .hero h1{font-size:24px}
    .hero p{font-size:13.5px;margin-top:7px}
    .hero .kicker{margin-bottom:5px}
    .hub{margin-top:17px;gap:9px}
    .hub-card{padding:13px}
    .hub-card h3{font-size:17px}
    .hub-card p{font-size:12.5px}
    .hub-card .hc-meta{margin-top:6px;padding-top:7px}
    #view{--page-pad:15px}
    #view-body{padding:16px var(--page-pad) 60px}
    .card-grid{grid-template-columns:1fr}
    .rowcard{flex-wrap:wrap}
    .rowcard .rc-acts{width:100%}
  }

  /* ---------- what is this part ---------- */
  .pi-figure{
    background:var(--panel-2);border:1px solid var(--line);border-radius:12px;
    padding:10px;margin:2px 0 14px;
  }
  .part-diagram{display:block;width:100%;height:275px}
  .pi-h{
    font-family:var(--font-display);font-size:11px;letter-spacing:.1em;text-transform:uppercase;
    color:var(--ink-soft);margin:14px 0 5px;
  }
  .pi-p{margin:0;font-size:12.5px;line-height:1.6;color:var(--ink)}
  .pi-pins{width:100%;border-collapse:collapse;font-size:12.5px}
  .pi-pins td{padding:5px 0;border-bottom:1px solid var(--line-soft);vertical-align:top}
  .pi-pins td:first-child{width:74px;color:var(--copper-deep);font-family:var(--font-mono);font-size:11.5px}
  .pi-steps{margin:4px 0 0;color:var(--ink)}
  .pi-steps li{margin:4px 0}
  .pi-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
  .btn.wide{width:100%}

  /* right-click menu on a part */
  .ctx-menu{
    position:fixed;z-index:80;min-width:186px;background:var(--panel);
    border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow-pop);
    padding:5px;display:flex;flex-direction:column;
  }
  .ctx-title{
    font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft);
    padding:5px 8px 6px;border-bottom:1px solid var(--line-soft);margin-bottom:4px;
  }
  .ctx-menu button{
    text-align:left;border:0;background:transparent;border-radius:7px;padding:7px 9px;
    font-family:var(--font-ui);font-size:12.5px;color:var(--ink);cursor:pointer;
  }
  .ctx-menu button:hover{background:var(--line-soft)}
  .ctx-menu button:first-of-type{color:var(--copper-deep);font-weight:600}

  /* ---------- modal ---------- */
  /* Above the EXPANDED palette (z-index 70), or a dialog opened from inside
     the expanded block editor — Examples, Clear all, the ? on a block —
     opens behind the panel that asked for it and reads as a dead button. */
  #modal-backdrop{position:fixed;inset:0;background:rgba(34,39,46,.42);display:grid;place-items:center;z-index:90}
  #modal-backdrop[hidden]{display:none}
  #modal{
    width:min(520px,92vw);max-height:86vh;overflow-y:auto;background:var(--panel);
    border-radius:14px;box-shadow:var(--shadow-pop-lg);padding:20px 22px;
  }
  #modal h3{margin:0 0 4px;font-family:var(--font-display);font-size:17px}
  #modal .sub{color:var(--ink-soft);font-size:12.5px;margin:0 0 16px;line-height:1.55}
  #modal .actions{display:flex;gap:8px;justify-content:flex-end;margin-top:16px}

  /* ---------- toast ---------- */
  #toast{
    position:fixed;left:50%;bottom:22px;transform:translateX(-50%);z-index:70;
    background:rgba(34,39,46,.92);color:#f2f3ee;font-size:12.5px;padding:9px 16px;border-radius:10px;
    box-shadow:0 6px 20px rgba(0,0,0,.2);max-width:70vw;
  }
  #toast[hidden]{display:none}
  #toast.good{background:#1c6b40}
  #toast.bad{background:#9a3423}

  /* ---------- experiment mode ---------- */
  .xp-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
  .xp-read{
    background:var(--panel-2);border:1px solid var(--line);border-radius:10px;padding:10px 12px;
  }
  .xp-read .k{font-size:11px;color:var(--ink-soft)}
  .xp-read .v{font-family:var(--font-display);font-size:19px;font-weight:600;font-variant-numeric:tabular-nums}
  .predict{display:flex;gap:6px;flex-wrap:wrap;margin-top:6px}
  .predict button{
    border:1px solid var(--line);background:var(--panel-2);border-radius:999px;padding:5px 11px;
    font-size:12px;cursor:pointer;font-family:var(--font-ui);color:var(--ink);
  }
  .predict button:hover{border-color:var(--copper)}
  .predict button.picked{background:var(--copper-soft);border-color:var(--copper);color:var(--copper-deep)}

  @media (max-width:900px){
    #palette{width:170px}
    #dock{width:330px}
    .tb-btn span.lbl{display:none}
  }
  @media (max-width:680px){
    #app{min-width:0;overflow-x:hidden}
    #main{min-width:0}
    #palette{width:142px}
    #dock{width:min(88vw,360px)}
    #docname{width:104px}
  }

  /* ==================================================================
     the cloud chip and the sign-in item
     ------------------------------------------------------------------
     Two small additions, and nothing else on either surface moves. Every
     colour below is an existing token: --accent-deep for anything that
     carries a label (--accent scores 3.46:1 on white and cannot), --live-deep
     for saved, --danger for a failed sync, --ink-soft for offline. The chip
     borrows .tb-btn’s metrics so it sits on the workspace toolbar without
     changing its rhythm.
     ================================================================== */
  .cloud-chip{
    display:inline-flex;align-items:center;gap:6px;
    height:28px;padding:0 10px;flex:none;
    font-family:var(--font-ui);font-size:11.5px;font-weight:600;letter-spacing:.01em;
    white-space:nowrap;border-radius:999px;cursor:pointer;
    background:var(--panel-2);color:var(--ink-soft);
    border:1px solid var(--line);
    transition:background .12s,border-color .12s,color .12s;
  }
  .cloud-chip:hover{border-color:var(--accent);color:var(--accent-deep)}
  .cloud-chip:focus-visible{outline:2px solid var(--accent-deep);outline-offset:1px}
  .cloud-chip[hidden]{display:none}

  .cloud-chip.out{background:var(--accent-soft);color:var(--accent-deep);border-color:var(--accent)}
  .cloud-chip.ok{color:var(--live-deep);border-color:var(--line-soft)}
  .cloud-chip.working{color:var(--accent-deep);border-color:var(--accent)}
  .cloud-chip.offl{color:var(--ink-soft);border-color:var(--line)}
  /* --danger itself is 4.37:1 on this tint, which is under the AA floor at
     11.5px. The border keeps the brand red; the LABEL takes a deeper ink. */
  .cloud-chip.bad{color:#A8352F;border-color:var(--danger);background:#FDF1F0}

  /* "Saving…" should be noticed, never demand attention */
  .cloud-chip.working{animation:cloudPulse 1.6s ease-in-out infinite}
  @keyframes cloudPulse{0%,100%{opacity:1}50%{opacity:.62}}
  @media (prefers-reduced-motion:reduce){ .cloud-chip.working{animation:none} }

  /* the workspace toolbar is 52px of 30px controls — line the chip up */
  #topbar .cloud-chip{height:30px}

  /* ------------------------------------------------------------------
     the account dialog
     ------------------------------------------------------------------
     Sign in, create an account, verify an email, reset a password. It is
     drawn inside the application’s own modal with the application’s own
     .field / .btn / .sub classes; everything below is the handful of
     extras those do not already cover. No existing rule was changed.
     ------------------------------------------------------------------ */
  .hmenu-item.cloud-signin .mi-ic{display:inline-flex;align-items:center;justify-content:center}

  .authbox{max-width:400px}
  .authbox .field{margin-bottom:10px}
  .authbox .field + .auth-hint{margin:-6px 0 12px}

  /* a line of guidance under a field: quieter than the label, still AA */
  .auth-hint{font-size:11.5px;line-height:1.45;color:var(--ink-faint)}

  /* what went wrong, and what is merely worth knowing */
  .auth-err,.auth-note{
    font-size:12.5px;line-height:1.5;border-radius:8px;
    padding:8px 10px;margin:0 0 12px;border:1px solid;
  }
  .auth-err{color:#A8352F;background:#FDF1F0;border-color:var(--danger)}
  .auth-note{color:var(--accent-deep);background:var(--accent-soft);border-color:var(--accent)}

  /* the one-time code: wide, monospaced and spaced out, because it is
     copied digit by digit out of an email */
  .authbox input.auth-otp{
    font-family:var(--font-mono);font-size:20px;font-weight:500;
    letter-spacing:.34em;text-align:center;padding:8px 10px;
  }

  /* "New here? Create an account" — a button that reads as a link */
  .auth-alt{
    margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft);
    font-size:12.5px;color:var(--ink-soft);
  }
  .authbox .linkish{
    background:none;border:0;padding:0;cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;font-weight:600;
    color:var(--accent-deep);text-decoration:underline;
  }
  .authbox .linkish:hover{color:var(--accent-dark)}
  .authbox .linkish:focus-visible{outline:2px solid var(--accent-deep);outline-offset:2px;border-radius:3px}

  /* "or, if the email has a 6-digit code" — a rule with the words sitting
     in it, so the two routes read as alternatives rather than as steps */
  .auth-or{display:flex;align-items:center;gap:10px;margin:14px 0 10px;
    font-size:11.5px;color:var(--ink-faint)}
  .auth-or::before,.auth-or::after{content:"";flex:1;height:1px;background:var(--line-soft)}

  /* the read-only half of the account screen */
  .auth-row{
    display:flex;align-items:baseline;gap:8px;
    padding:7px 0;border-bottom:1px solid var(--line-soft);font-size:13px;
  }
  .auth-row span{flex:0 0 96px;color:var(--ink-faint);font-size:12px}
  .auth-row b{color:var(--ink);font-weight:600;word-break:break-all}
  .auth-row i{margin-left:auto;font-style:normal;font-size:11px;white-space:nowrap}

  /* verified / not verified. --live-deep and the deep red both clear AA
     on white; the vivid tokens do not, at this size. */
  .auth-hint-inline{color:var(--ink-faint)}

  /* A guided project's steps are the project. There is no ✕ on them:
     closing the one panel that says what to do next left learners on a
     canvas with no way to read the step they were on. The Steps button
     in the toolbar still opens and closes it. */
  body.train-mode #dock-close{display:none}

  /* a lesson held back until sign-in, drawn like the locked project card */
  .cl-card.is-locked{opacity:.62;cursor:pointer}
  .cl-card.is-locked .cl-n{background:var(--line-soft);color:var(--ink-faint)}
  .cl-card.is-locked b{color:var(--ink-soft)}

  .auth-ok{color:var(--live-deep);font-weight:600}
  .auth-warn{color:#A8352F;font-weight:600}

  /* below ~680px the toolbar already scrolls sideways (the media query above
     sets that up); the chip just gets tighter rather than trying to reflow */
  @media (max-width:680px){
    #topbar .cloud-chip{padding:0 8px;font-size:11px}
  }


  /* =====================================================================
     Plans, pricing, and the two role dashboards
     ---------------------------------------------------------------------
     Same visual language as the rest of the pages: a .mod is still one
     white panel, .kpi is still the number tile, table.data is still the
     table. Nothing here introduces a second design system, and nothing
     here restyles anything a student already sees.
     ===================================================================== */

  /* one note paragraph, in a class of its own — .sub is used by modals and
     by the steps panel with different meanings, so it is left alone */
  .pnote{margin:14px 0 0;font-size:12.5px;color:var(--ink-soft);line-height:1.6;max-width:70ch}

  /* ---- the plan cards ---- */
  .plan-grid{
    display:grid;gap:14px;margin-top:22px;
    grid-template-columns:repeat(auto-fit,minmax(258px,1fr));
    align-items:stretch;
  }
  .plan-card{
    position:relative;display:flex;flex-direction:column;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:16px;
    padding:20px 20px 18px;
  }
  /* Premium is the complete plan, so it is the one that is drawn as such.
     It is a border and a flag, not a bigger card — a card that grows makes
     the other two look broken rather than cheaper. */
  .plan-card.is-best{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
  .plan-card.is-mine{border-color:var(--live);box-shadow:0 0 0 1px var(--live)}
  .plan-flag{
    position:absolute;top:-10px;left:20px;
    background:var(--accent-deep);color:#fff;border-radius:999px;
    font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
    padding:4px 10px;
  }
  .plan-card h3{
    margin:2px 0 4px;font-family:var(--font-display);font-size:19px;font-weight:600;
  }
  .plan-tag{margin:0 0 14px;font-size:12.5px;color:var(--ink-soft);line-height:1.5;min-height:2.6em}

  /* the price. The struck-through original only ever appears once a code
     has come back valid from the database — see v_pricing. */
  .pp{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
  .pp .now{
    font-family:var(--font-display);font-size:27px;font-weight:600;line-height:1.2;
    font-variant-numeric:tabular-nums;color:var(--ink);
  }
  .pp .was{
    font-size:15px;color:var(--ink-faint);text-decoration:line-through;
    font-variant-numeric:tabular-nums;
  }
  .pp-off{
    margin-top:5px;display:inline-block;
    background:var(--live-fill,#D5F2E9);color:var(--live-deep);
    border-radius:999px;padding:3px 9px;font-size:11px;font-weight:600;
  }

  .plan-list{list-style:none;margin:15px 0 0;padding:0;flex:1}
  .plan-list li{
    position:relative;padding:5px 0 5px 22px;font-size:12.5px;line-height:1.5;
    color:var(--ink);
  }
  .plan-list li::before{position:absolute;left:0;top:5px;font-weight:700}
  .plan-list li.yes::before{content:"✓";color:var(--live-deep)}
  .plan-list li.no{color:var(--ink-faint)}
  .plan-list li.no::before{content:"✕";color:var(--ink-faint);font-weight:600}

  /* ---- the reseller code box on a paid card ---- */
  .pcode{margin-top:15px;padding-top:14px;border-top:1px solid var(--line-soft)}
  .pcode-in{display:flex;gap:7px}
  .pcode-in .in{flex:1;min-width:0}
  .pcode-ok{
    font-size:12px;color:var(--live-deep);font-weight:600;
    display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  }
  .pcode-no{margin-top:7px;font-size:11.5px;color:#A8352F;line-height:1.45}
  .plan-cta{margin-top:15px}
  .plan-cta .btn{width:100%;justify-content:center}

  /* UPGRADING. Two real choices on one card, and only one of them is the
     primary action: the prorated upgrade leads, the full term follows as
     a quiet second line. The sentence between them says what the cheaper
     number actually buys — without it, "Upgrade ₹384" beside "₹1,499"
     reads as a discount rather than as a shorter piece of access. */
  .plan-up{
    margin-top:8px;font-size:11.5px;line-height:1.5;color:var(--ink-soft);
    text-align:center;
  }
  .plan-cta .btn.linky-btn{
    margin-top:8px;background:none;border:none;box-shadow:none;
    height:auto;padding:2px 0;font-size:11.5px;color:var(--accent-deep);
    text-decoration:underline;text-underline-offset:2px;
  }
  .plan-cta .btn.linky-btn:hover{color:var(--ink);background:none}

  /* the one text input this layer adds, styled like .field input already is */
  .in{
    width:100%;height:33px;padding:0 10px;border:1px solid var(--line);
    border-radius:9px;background:var(--panel-2);color:var(--ink);
    font-family:var(--font-ui);font-size:12.5px;
  }
  .in:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}
  #rc-new{margin:4px 0 6px}

  .linky{
    background:none;border:0;padding:0;cursor:pointer;
    font:inherit;font-weight:500;color:var(--accent-deep);text-decoration:underline;
  }

  /* ---- the plan badge, used on the account menu and in both tables ---- */
  .plan-chip{
    display:inline-block;border-radius:999px;padding:2px 9px;
    font-size:11px;font-weight:700;letter-spacing:.03em;
    border:1px solid transparent;
  }
  .plan-chip.p-free    {background:var(--line-soft);   color:var(--ink-soft)}
  .plan-chip.p-standard{background:var(--sb-code-fill);color:var(--sb-code-ink);border-color:var(--sb-code)}
  .plan-chip.p-premium {background:var(--sb-chal-fill);color:var(--sb-chal-ink);border-color:var(--sb-chal)}

  .hmenu-plan{padding:4px 12px 9px;display:flex;flex-direction:column;gap:4px;align-items:flex-start}
  .hmenu-plan small{font-size:11px;color:var(--ink-soft)}

  /* ---- a card held back by the PLAN rather than by the session ---- */
  .tcard.is-locked.is-premium{opacity:.72}
  .tcard.is-locked.is-premium .go{color:var(--sb-chal-ink);font-weight:600}

  /* ---- the comparison table, and any wide table on a narrow phone ---- */
  .tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table.data.compare th:not(:first-child),
  table.data.compare td:not(:first-child){text-align:center;width:19%}
  table.data td.yes {color:var(--live-deep);font-weight:600}
  table.data td.no  {color:var(--ink-faint)}
  table.data td.part{color:var(--ink-soft);font-size:11.5px}

  /* ---- the reseller's code ---- */
  .rcode{
    font-family:var(--font-mono);font-size:11.5px;font-weight:600;
    background:var(--line-soft);border-radius:6px;padding:2px 7px;letter-spacing:.06em;
  }
  .rcode.big{
    font-size:22px;padding:9px 16px;border-radius:11px;letter-spacing:.14em;
    background:var(--accent-soft);color:var(--accent-deep);
  }
  .codebox{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
  .cb-acts{display:flex;gap:7px;flex-wrap:wrap}

  .pill.on {background:#e3f2e8;color:#1c6b40}
  .pill.off{background:var(--line-soft);color:var(--ink-faint)}

  /* the purchase summary inside the confirm dialog */
  #modal table.data.buy-sum{margin:14px 0 4px}
  table.data.buy-sum tr.tot td{border-top:1px solid var(--line);font-size:13.5px}

  /* ---- narrow screens ----
     The cards already reflow (auto-fit). What needs saying is that a table
     must scroll inside its own box rather than widening the page. */
  @media (max-width: 700px){
    .plan-grid{grid-template-columns:1fr;gap:12px}
    .plan-tag{min-height:0}
    .pcode-in{flex-direction:column}
    .pcode-in .btn{width:100%;justify-content:center}
    .codebox{gap:10px}
    .rcode.big{font-size:18px;letter-spacing:.1em}
    table.data.compare{min-width:420px}
    #adm-resellers table.data,#adm-students table.data,#res-students table.data{min-width:640px}
  }

  /* .pcode-ok carries display:flex, which outranks the UA's [hidden] rule —
     the availability line in the reseller-code dialog would never hide. */
  .pcode-ok[hidden]{display:none}
  #rc-ok{margin-top:7px}

  /* ---- Monthly / Yearly ----
     Two views of one price list, so it is a switch above the cards rather
     than more cards. */
  .cycle-pick{
    display:inline-flex;gap:3px;margin:22px 0 0;padding:3px;
    background:var(--line-soft);border-radius:999px;
  }
  .cycle-pick .cyc{
    display:inline-flex;align-items:center;gap:7px;
    border:0;background:transparent;cursor:pointer;
    font-family:var(--font-ui);font-size:12.5px;font-weight:600;color:var(--ink-soft);
    padding:7px 15px;border-radius:999px;
  }
  .cycle-pick .cyc:hover{color:var(--ink)}
  .cycle-pick .cyc.on{background:var(--panel-2);color:var(--accent-deep);box-shadow:0 1px 2px rgba(15,44,78,.12)}
  .cyc-tag{
    background:var(--sb-chal-fill);color:var(--sb-chal-ink);
    border-radius:999px;padding:2px 7px;font-size:10.5px;font-weight:700;
    letter-spacing:.02em;white-space:nowrap;
  }
  .cycle-pick .cyc.on .cyc-tag{background:var(--sb-chal);color:#fff}

  /* what a yearly price works out at per month — the bigger number needs
     the smaller one beside it or it reads as more expensive */
  .pp-sub{margin-top:6px;font-size:11.5px;color:var(--ink-soft);line-height:1.5}
  .pp-sub b{color:var(--ink)}

  @media (max-width: 700px){
    .cycle-pick{display:flex;width:100%}
    .cycle-pick .cyc{flex:1;justify-content:center;padding:8px 10px}
    .cyc-tag{display:none}
  }

  /* ---- the 12-month offer, said prominently on the card ----
     The thing that makes a bigger number cheaper is the two free months,
     so it is a block on the card rather than a footnote under it. */
  .pp-offer{
    margin-top:9px;padding:9px 11px;border-radius:10px;
    background:var(--sb-chal-fill);border:1px solid var(--sb-chal);
    display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  }
  .pp-offer b{font-size:12.5px;color:var(--sb-chal-ink);line-height:1.4;flex:1;min-width:0}
  .pp-free{
    flex:none;background:var(--sb-chal);color:#fff;border-radius:999px;
    padding:3px 9px;font-size:10.5px;font-weight:700;letter-spacing:.04em;white-space:nowrap;
  }

  /* ---- pay as you go ----
     Said once, at the top, because "will this charge me again?" is the
     first question anybody has about a price. */
  .pay-banner{
    margin-top:20px;padding:13px 16px;border-radius:12px;
    background:var(--accent-soft);border:1px solid var(--accent);
  }
  .pay-banner b{display:block;font-size:13px;color:var(--accent-deep);margin-bottom:3px}
  .pay-banner span{font-size:12px;color:var(--ink-soft);line-height:1.55}
  #modal .pay-note{
    margin:14px 0 10px;padding:11px 13px;border-radius:10px;
    background:var(--accent-soft);font-size:12.5px;line-height:1.55;color:var(--ink);
  }
  #modal .pay-note b{color:var(--accent-deep)}

  /* =====================================================================
     the legal pages (js/06-legal.js) and the site footer
     ---------------------------------------------------------------------
     A legal document is read, not scanned, so it is the one page here that
     is a COLUMN rather than a grid of modules: one white sheet, one
     reading measure, and a clear step in size between a heading and the
     paragraph under it. Everything is written in the page tokens the rest
     of #view already uses, so it inherits the palette and the type scale
     and cannot drift from them.
     ===================================================================== */
  .legal-doc{
    max-width:74ch;margin:0 auto;
    background:var(--sb-panel);border:1px solid var(--sb-line);border-radius:16px;
    padding:30px 34px 34px;
    box-shadow:0 1px 2px rgba(15,23,42,.05);
  }
  .legal-back{margin-bottom:20px}
  .legal-title{
    font-family:var(--font-display);font-size:29px;line-height:1.2;
    margin:0 0 8px;color:var(--ink);
  }
  .legal-updated{
    margin:0 0 22px;padding-bottom:18px;border-bottom:1px solid var(--sb-line);
    font-size:13px;color:var(--ink-soft);
  }
  .legal-updated strong{color:var(--ink)}
  .legal-intro p{
    font-size:15px;line-height:1.75;color:var(--ink);margin:0 0 14px;
  }
  .legal-sec{margin-top:30px;scroll-margin-top:16px}
  .legal-sec h2{
    font-family:var(--font-display);font-size:18px;line-height:1.35;
    margin:0 0 10px;color:var(--ink);
  }
  .legal-sec p{font-size:14.5px;line-height:1.75;color:var(--ink-soft);margin:0 0 12px}
  .legal-sec p:last-child,.legal-sec ul:last-child{margin-bottom:0}
  .legal-list{margin:0 0 12px;padding-left:22px}
  .legal-list li{
    font-size:14.5px;line-height:1.7;color:var(--ink-soft);margin-bottom:6px;
  }
  .legal-quote{
    margin:0 0 12px !important;padding:11px 14px;border-radius:10px;
    background:var(--accent-soft);border-left:3px solid var(--accent);
    color:var(--ink) !important;font-weight:500;
  }
/* The Privacy Policy groups its sections under named sub-headings that
     are part of the supplied copy ("Account Information", "Providing the
     Platform"). They have to read as a level BELOW the numbered section
     heading and above the paragraph, or the page loses its shape. */
  .legal-sub{
    font-family:var(--font-display);font-size:14.5px;line-height:1.4;
    margin:20px 0 8px;color:var(--ink);
  }
  .legal-sec .legal-sub:first-of-type{margin-top:16px}

  /* The other legal page, at the foot of this one: somebody reading these
     is one click from wanting the other. */
  .also-sep{margin:0 8px;color:var(--sb-line)}
  .legal-also{
    margin-top:26px;padding-top:16px;border-top:1px solid var(--sb-line);
    font-size:13px;color:var(--ink-faint);
  }
  @media (max-width: 700px){
    .legal-sub{font-size:14px}
  }
  .legal-mail{color:var(--accent-deep);font-weight:500;text-decoration:underline}
  .legal-mail:hover{color:var(--sb-action-dark)}
  .legal-signoff{
    margin-top:34px;padding-top:20px;border-top:1px solid var(--sb-line);
  }
  .legal-signoff p{font-size:14px;line-height:1.7;color:var(--ink);margin:0 0 4px}

  @media (max-width: 700px){
    .legal-doc{padding:20px 17px 24px;border-radius:14px}
    .legal-title{font-size:24px}
    .legal-sec{margin-top:24px}
    .legal-sec h2{font-size:16.5px}
    .legal-intro p,.legal-sec p,.legal-list li{font-size:14px}
  }

  /* ---- the footer, under every page ----
     One row on a wide screen, one column on a narrow one. It is quiet on
     purpose: nothing down here competes with the page's own action. */
  .site-foot{
    max-width:1180px;margin:44px auto 0;padding-top:18px;
    border-top:1px solid var(--sb-line);
  }
  .foot-in{
    display:flex;flex-wrap:wrap;align-items:center;gap:10px 18px;
    font-size:12.5px;color:var(--ink-faint);
  }
  .foot-brand{font-family:var(--font-display);color:var(--ink-soft)}
  .foot-links{display:flex;flex-wrap:wrap;align-items:center;gap:8px 16px}
  .foot-link{
    font:inherit;color:var(--accent-deep);background:none;border:0;padding:0;
    cursor:pointer;text-decoration:underline;text-underline-offset:2px;
  }
  .foot-link:hover{color:var(--sb-action-dark)}
  .foot-copy{margin-left:auto}
  @media (max-width: 700px){
    .foot-in{flex-direction:column;align-items:flex-start;gap:8px}
    .foot-copy{margin-left:0}
  }

  /* =====================================================================
     Block coding — the kit's categories (js/07-blockkit.js)
     ---------------------------------------------------------------------
     Script 3's three colours (output green, control orange, variables
     purple) are untouched and keep their meaning. These are the drawers the
     kit adds, and they follow the same rule: one hue per category, dark
     enough that white text on it clears AA at block-label size. Timing and
     Basic deliberately sit near control's orange, because waiting and
     deciding are the same kind of thing to a learner.
     ===================================================================== */
  .cat-basic    > .blk-head, .bm-item.cat-basic{background:#6b7a86}
  .cat-logic    > .blk-head, .bm-item.cat-logic{background:#e2762c}
  .cat-loops    > .blk-head, .bm-item.cat-loops{background:#c96a1f}
  .cat-variables> .blk-head, .bm-item.cat-variables{background:#8e5bb5}
  .cat-input    > .blk-head, .bm-item.cat-input{background:#1f7fa8}
  .cat-timing   > .blk-head, .bm-item.cat-timing{background:#9a6a2f}
  .cat-motors   > .blk-head, .bm-item.cat-motors{background:#3f6fb5}
  .cat-sensors  > .blk-head, .bm-item.cat-sensors{background:#177b86}
  .cat-comm     > .blk-head, .bm-item.cat-comm{background:#57699b}
  .cat-robotics > .blk-head, .bm-item.cat-robotics{background:#2f6f5f}
  .cat-advanced > .blk-head, .bm-item.cat-advanced{background:#5a5f66}
  .cat-basic{background:#6b7a86}      .cat-logic{background:#e2762c}
  .cat-loops{background:#c96a1f}      .cat-variables{background:#8e5bb5}
  .cat-input{background:#1f7fa8}      .cat-timing{background:#9a6a2f}
  .cat-motors{background:#3f6fb5}     .cat-sensors{background:#177b86}
  .cat-comm{background:#57699b}       .cat-robotics{background:#2f6f5f}
  .cat-advanced{background:#5a5f66}

  /* =====================================================================
     Blocks that look like blocks
     ---------------------------------------------------------------------
     The stacks used to be flat rectangles in a list: correct, readable, and
     not obviously a jigsaw. These rules give them the shape every learner
     already knows from Scratch and MakeCode — a notch on top, a tab
     underneath, a hat wrapping the whole stack, and readings as rounded
     pills nested inside the block that uses them.

     THE SHAPE IS ONE clip-path, NOT A PILE OF PSEUDO-ELEMENTS.
     Each block reserves --nub-h at the bottom of its own box. The clip cuts
     a notch out of the top edge and leaves only the tab sticking down into
     that reserved strip; the block below is pulled up by the same amount, so
     ITS notch sits exactly over the tab above. The tab shows through because
     the notch is a real hole and the block above is painted first. Nothing
     is drawn in the background colour and nothing has to know what it is
     sitting on, which is what makes it work inside a C-block as well as on
     the workspace.

     Change --nub-* and every block, hat, mouth and foot follows.
     ===================================================================== */
  #blocks-pane, .cl-blocks{
    --nub-l:14px;      /* how far in the notch starts        */
    --nub-r:36px;      /* and where it ends                  */
    --nub-il:18px;     /* the flat part of it                */
    --nub-ir:32px;
    --nub-h:5px;       /* how deep                           */
    --blk-r:6px;       /* the corner radius the clip allows  */
  }

  /* the block itself carries no paint any more — the head and foot do */
  #blocks-pane .blk, .cl-blocks .blk{
    border:0;border-radius:0;box-shadow:none;position:relative;
    margin-bottom:calc(var(--nub-h) * -1);      /* the next block laps over the tab */
  }
  #blocks-pane .blk-body, .cl-blocks .blk-body{gap:0}

  /* a plain block: notch on top, tab underneath */
  #blocks-pane .blk:not(.cblock) > .blk-head,
  .cl-blocks .blk:not(.cblock) > .blk-head{
    border-radius:var(--blk-r);
    padding-bottom:calc(7px + var(--nub-h));
    clip-path:polygon(
      0 0, var(--nub-l) 0, var(--nub-il) var(--nub-h),
      var(--nub-ir) var(--nub-h), var(--nub-r) 0, 100% 0,
      100% calc(100% - var(--nub-h)), var(--nub-r) calc(100% - var(--nub-h)),
      var(--nub-ir) 100%, var(--nub-il) 100%,
      var(--nub-l) calc(100% - var(--nub-h)), 0 calc(100% - var(--nub-h)));
  }
  /* a C block: the head takes the notch, the foot takes the tab, and the
     mouth between them is inset so what is inside reads as inside */
  #blocks-pane .blk.cblock > .blk-head, .cl-blocks .blk.cblock > .blk-head{
    border-radius:var(--blk-r) var(--blk-r) 0 0;
    clip-path:polygon(
      0 0, var(--nub-l) 0, var(--nub-il) var(--nub-h),
      var(--nub-ir) var(--nub-h), var(--nub-r) 0, 100% 0, 100% 100%, 0 100%);
  }
  #blocks-pane .blk.cblock > .blk-body, .cl-blocks .blk.cblock > .blk-body{
    margin:0 0 0 13px;background:var(--panel-2);border-radius:0;
    padding:7px 7px calc(7px + var(--nub-h)) 7px;
  }
  #blocks-pane .blk-foot, .cl-blocks .blk-foot{
    height:auto;min-height:calc(9px + var(--nub-h));border-radius:0 0 var(--blk-r) var(--blk-r);
    padding-bottom:var(--nub-h);
    clip-path:polygon(
      0 0, 100% 0, 100% calc(100% - var(--nub-h)),
      var(--nub-r) calc(100% - var(--nub-h)), var(--nub-ir) 100%, var(--nub-il) 100%,
      var(--nub-l) calc(100% - var(--nub-h)), 0 calc(100% - var(--nub-h)));
  }
  #blocks-pane .blk-mid, .cl-blocks .blk-mid{padding:5px 12px;font-weight:600}

  /* ---- the hat: the stack's header wraps everything under it ---- */
  #blocks-pane .stack, .cl-blocks .stack{
    background:#7a6ea8;border:0;border-radius:12px 12px 10px 10px;
    padding:0 0 13px 11px;overflow:visible;
  }
  #blocks-pane .stack:has(.cat-loop), .cl-blocks .stack:has(.cat-loop){background:#54700B}
  #blocks-pane .stack-head, .cl-blocks .stack-head{
    background:transparent;padding:10px 12px 9px;
  }
  #blocks-pane .blk-body.root, .cl-blocks .blk-body.root{
    background:var(--panel-2);border-radius:9px 0 0 9px;padding:9px;
  }
  #blocks-pane .stack-empty, .cl-blocks .stack-empty{margin:0}
  #blocks-pane .blk-add, .cl-blocks .blk-add{margin-top:calc(6px + var(--nub-h))}

  /* ---- fields: a dropdown is a dark pill, a number is a white one ---- */
  #blocks-pane .bfld, .cl-blocks .bfld{
    border-radius:999px;height:23px;padding:2px 7px;font-weight:500;
  }
  #blocks-pane select.bfld, .cl-blocks select.bfld{
    background:rgba(0,0,0,.24);color:#fff;padding-left:10px;font-style:normal;
  }
  #blocks-pane select.bfld option, .cl-blocks select.bfld option{color:var(--ink);background:#fff}
  #blocks-pane input.bfld, .cl-blocks input.bfld{
    background:#fff;color:var(--ink);text-align:center;
  }
  #blocks-pane .bfld.num, .cl-blocks .bfld.num{width:56px}

  /* ---- a reading is a rounded block sitting inside the one using it ---- */
  #blocks-pane .vslot, .cl-blocks .vslot{
    border-radius:999px;padding:3px 7px;gap:5px;background:rgba(0,0,0,.22);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.10);
  }
  #blocks-pane .vslot .vslot, .cl-blocks .vslot .vslot{background:rgba(0,0,0,.18)}
  #blocks-pane .pin-note, .cl-blocks .pin-note{opacity:.72}

  /* The whole block is the handle now, so the grip is one more thing on a
     crowded row saying what the block already says by being draggable. */
  #blocks-pane .blk .grip, .cl-blocks .blk .grip{display:none}
  #blocks-pane .blk > .blk-head, .cl-blocks .blk > .blk-head{cursor:grab}
  #blocks-pane.ro .blk > .blk-head{cursor:default}
  #blocks-pane .blk > .blk-head .bfld,
  #blocks-pane .blk > .blk-head button{cursor:auto}
  #blocks-pane .blk > .blk-head button{cursor:pointer}
  .blk.bl-dragging{opacity:.35}
  .bl-ghost.bl-ghost-blk{background:transparent;padding:0;box-shadow:0 8px 20px rgba(0,0,0,.3)}

  /* A block is as wide as what it says. Stretching each one to the panel
     width made a column of identical bars, which is the look these rules
     exist to get away from — and it put every delete button in a line down
     the right-hand edge, miles from the block it belongs to. */
  #blocks-pane .blk, .cl-blocks .blk{align-self:flex-start;max-width:100%}
  #blocks-pane .blk-head, .cl-blocks .blk-head{flex-wrap:nowrap}
  #blocks-pane .blk.cblock, .cl-blocks .blk.cblock{align-self:stretch}
  #blocks-pane .blk-x, .cl-blocks .blk-x{margin-left:4px}

  /* A slightly deeper, wider nub than the first pass: at 5px the jigsaw was
     geometrically right and visually invisible. */
  #blocks-pane, .cl-blocks{
    --nub-l:16px; --nub-il:21px; --nub-ir:37px; --nub-r:42px; --nub-h:6px;
  }
  /* The three controls on every block — help, duplicate, delete — are ours
     rather than Scratch's, where the same things live behind a right-click
     no child finds. They stay visible enough to tap on a tablet and quiet
     enough that the sentence is what you read. */
  #blocks-pane .blk-x, #blocks-pane .blk-help{opacity:.45;transition:opacity .12s}
  #blocks-pane .blk:hover > .blk-head .blk-x,
  #blocks-pane .blk:hover > .blk-head .blk-help,
  #blocks-pane .blk:focus-within > .blk-head .blk-x,
  #blocks-pane .blk:focus-within > .blk-head .blk-help,
  #blocks-pane .blk-foot .blk-x{opacity:1}
  #blocks-pane .blk-help{
    border:0;background:rgba(255,255,255,.22);color:#fff;border-radius:999px;
    width:18px;height:18px;font-size:11px;line-height:1;cursor:pointer;flex:none;
  }

  /* "is less than" does not fit in 44px, and a comparison that reads "is le"
     teaches nothing. The operator sizes to its own words. */
  #blocks-pane .bfld.op, .cl-blocks .bfld.op{width:auto;min-width:56px;text-align:left}
  #blocks-pane .bfld, .cl-blocks .bfld{max-width:none}

  /* A drag has to beat the browser's own gesture. Without this a finger on
     a block scrolls the workspace instead of picking the block up, which is
     the same "drag does not work" from a tablet's point of view. */
  #blocks-pane .blk > .blk-head, .bl-item{touch-action:none}

  /* =====================================================================
     The Block Lab — a Scratch-shaped workspace (js/08-blocklab.js)
     ---------------------------------------------------------------------
     Three columns and nothing else: a rail of categories, a drawer of
     blocks, and a free canvas the learner pans and zooms. The BLOCKS
     themselves are styled further up and are untouched; everything here is
     the frame around them, so removing js/08-blocklab.js leaves the old
     pane intact.

     THE DRAWER MUST NEVER COVER THE WORKSPACE. It used to: the flyout was
     position:absolute across the whole of .bl-main, which is the same box
     as the workspace — so there was nowhere to drop a block, and the blocks
     already there were behind it. Drag and drop was, in the mode almost
     everybody uses, unavailable. The flyout is an ordinary flex child in
     every mode now.

     THE CANVAS IS A CAMERA, NOT A SCROLLER. .bl-work is the window and
     .bl-cam is what moves inside it, carrying one transform for both pan
     and zoom. Scripts are positioned inside the camera, so their
     coordinates never change when the view does, and getBoundingClientRect
     still reports where a block really is — which is what lets the drop
     hit-testing keep working at any zoom with no matrix to undo.
     ===================================================================== */
  #blocks-pane:has(.bl-shell){padding:0;gap:0;overflow:hidden}
  .bl-shell{display:flex;flex-direction:column;min-height:0;height:100%;flex:1}

  /* ---- the toolbar. It WRAPS rather than scrolls: a toolbar that scrolls
     sideways hides its own controls, and nothing here is wide enough. ---- */
  .bl-bar{
    display:flex;align-items:center;flex-wrap:wrap;gap:6px;padding:6px 8px;flex:none;
    border-bottom:1px solid var(--line);background:var(--panel-2);
  }
  .bl-gap{flex:1}
  .bl-btn{
    border:1px solid var(--line);background:#fff;color:var(--ink);border-radius:8px;
    height:30px;min-width:30px;padding:0 7px;font-size:13px;cursor:pointer;flex:none;
    line-height:1;
  }
  .bl-btn.wide{padding:0 11px;font-size:12px}
  .bl-btn:hover{background:var(--panel);border-color:var(--accent)}
  .bl-btn.on{background:var(--accent-deep);border-color:var(--accent-deep);color:#fff}
  .bl-zoom{font-size:11.5px;color:var(--ink-soft);min-width:38px;text-align:center;flex:none}
  .bl-search input{
    border:1px solid var(--line);border-radius:8px;height:30px;padding:0 10px;
    font:inherit;font-size:12.5px;width:150px;background:#fff;color:var(--ink);
  }
  .bl-search input:focus{outline:2px solid var(--accent);outline-offset:-1px}
  .bl-level{display:flex;border:1px solid var(--line);border-radius:8px;overflow:hidden;flex:none}
  .bl-level button{
    border:0;background:#fff;color:var(--ink-soft);font:inherit;font-size:11.5px;
    padding:0 10px;height:30px;cursor:pointer;
  }
  .bl-level button.on{background:var(--accent-deep);color:#fff;font-weight:600}

  /* ---- rail · drawer · stage ---- */
  .bl-main{display:flex;flex-direction:column;min-height:0;flex:1}
  .bl-stage{display:flex;min-height:0;flex:1}

  /* CATEGORY NAMES ARE NEVER TRUNCATED. "Commu…" named nothing; every
     drawer shows its whole word and the rail scrolls if it must. */
  .bl-toolbox{
    flex:none;display:flex;flex-direction:row;gap:3px;padding:6px;
    overflow-x:auto;overflow-y:hidden;
    border-bottom:1px solid var(--line);background:var(--panel-2);
  }
  .bl-cat{
    display:flex;align-items:center;gap:5px;border:1px solid transparent;border-radius:999px;
    cursor:pointer;padding:5px 11px 5px 8px;background:#fff;color:var(--ink);
    font:inherit;font-size:12px;line-height:1.2;white-space:nowrap;flex:none;
  }
  .bl-cat:hover{border-color:var(--line);background:var(--panel)}
  .bl-cat.on{border-color:var(--ink);background:var(--panel);font-weight:600}
  /* the category colour as a dot rather than as the whole chip — a rail of
     twelve saturated pills is unreadable, and the dot is the thing that has
     to match the blocks inside the drawer */
  .bl-cat-dot{
    width:11px;height:11px;border-radius:50%;flex:none;
    box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
  }
  .cat-project .bl-cat-dot{background:#E8A317} .cat-basic .bl-cat-dot{background:#6b7a86}
  .cat-logic   .bl-cat-dot{background:#e2762c} .cat-loops .bl-cat-dot{background:#c96a1f}
  .cat-variables .bl-cat-dot{background:#8e5bb5} .cat-input .bl-cat-dot{background:#7a4fb5}
  .cat-output  .bl-cat-dot{background:#2e9e56} .cat-timing .bl-cat-dot{background:#9a6a2f}
  .cat-motors  .bl-cat-dot{background:#3f6fb5} .cat-sensors .bl-cat-dot{background:#177b86}
  .cat-comm    .bl-cat-dot{background:#57699b} .cat-robotics .bl-cat-dot{background:#2f6f5f}
  .cat-advanced .bl-cat-dot{background:#5a5f66}
  .bl-cat-em{font-size:13px;flex:none}

  .bl-flyout{
    flex:none;max-height:33%;display:flex;flex-direction:column;background:#fff;
    border-bottom:1px solid var(--line);
  }
  .bl-flyout-head{
    display:flex;align-items:center;gap:8px;padding:7px 10px;flex:none;
    font-size:12.5px;font-weight:600;border-bottom:1px solid var(--line);color:var(--ink);
  }
  .bl-flyout-hint{font-weight:400;font-size:11px;color:var(--ink-faint)}
  .bl-flyout-head .bl-x{
    margin-left:auto;border:0;background:transparent;color:var(--ink-soft);
    cursor:pointer;font-size:13px;line-height:1;padding:2px 4px;
  }
  .bl-flyout-body{
    padding:8px;display:flex;flex-direction:row;flex-wrap:wrap;gap:6px;overflow-y:auto;
  }
  /* A drawer item is a small copy of the block it becomes: same colour,
     same rounded shape, so what you pick up is what lands. */
  .bl-item{
    border:0;border-radius:8px;color:#fff;font:inherit;font-size:12px;line-height:1.3;
    padding:8px 11px;text-align:left;cursor:grab;flex:0 1 auto;
    box-shadow:0 1px 2px rgba(0,0,0,.18);
  }
  .bl-item:active{cursor:grabbing}
  .bl-item:hover{filter:brightness(1.08)}
  /* a reading is a rounded pill, everywhere it appears — including here */
  .bl-item.k-value{border-radius:999px;padding:8px 13px}
  .bl-item.cat-project{background:#B07A0C}
  .bl-empty{font-size:12px;color:var(--ink-faint);padding:8px 4px;flex:1 0 100%}

  /* ---- the workspace: a window onto a camera ---- */
  .bl-work{
    flex:1;min-width:0;position:relative;overflow:hidden;
    background:var(--paper);
    background-image:radial-gradient(circle, rgba(0,0,0,.10) 1px, transparent 1px);
    background-size:22px 22px;
    cursor:grab;touch-action:none;
  }
  .bl-work.panning{cursor:grabbing}
  .bl-cam{position:absolute;left:0;top:0;width:0;height:0;transform-origin:0 0}
  .bl-cam .stack{position:absolute;width:max-content;max-width:none}
  .bl-cam .stack.bl-moving{filter:drop-shadow(0 8px 16px rgba(0,0,0,.28))}
  #blocks-pane .stack-head{cursor:grab}
  #blocks-pane.ro .stack-head{cursor:default}
  .bl-script-help{
    border:0;background:rgba(255,255,255,.22);color:#fff;border-radius:999px;
    width:19px;height:19px;font-size:11px;line-height:1;cursor:pointer;flex:none;
    margin-left:6px;
  }
  .bl-script-help:hover{background:rgba(255,255,255,.42)}

  /* THE EMPTY WORKSPACE SAYS WHAT TO DO, and stops saying it at the first
     block. No modal, no tour, and no placeholder that reads like an error. */
  .bl-hint{
    position:absolute;left:50%;bottom:18px;transform:translateX(-50%);
    background:var(--ink);color:#fff;border-radius:999px;padding:8px 16px;
    font-size:12.5px;pointer-events:none;box-shadow:0 4px 14px rgba(0,0,0,.22);
    max-width:88%;text-align:center;
  }
  .bl-hint[hidden]{display:none}
  .bl-zoombar{
    position:absolute;right:10px;bottom:10px;display:flex;gap:4px;
    background:rgba(255,255,255,.94);border:1px solid var(--line);border-radius:9px;padding:3px;
  }
  .bl-zoombar .bl-btn{height:26px;min-width:26px;border:0;background:transparent}

  /* ---- "+ add here" is gone from the workspace ----
     Blocks arrive by being dragged. The button script 3 still renders stays
     in the markup — it is the whole interaction without this file — but on a
     root stack it is not shown, and inside a C block it becomes a quiet
     dashed slot that says where things go. */
  .bl-cam .blk-body.root > .blk-add{display:none}
  .bl-cam .blk-add{font-size:11px;padding:4px 9px;opacity:.55;border-style:dashed}
  .bl-cam .blk-add:hover{opacity:1}
  .bl-cam .stack-empty{
    font-size:11.5px;color:var(--ink-faint);border:1.5px dashed var(--line);
    border-radius:8px;padding:9px 12px;background:transparent;
  }

  /* ---- the drop indicator is the shadow of a block, not a hairline ---- */
  .drop-line{
    height:16px;border-radius:6px;margin:2px 0;background:rgba(0,0,0,.16);
    border:2px dashed rgba(0,0,0,.34);animation:none;
  }
  .bl-ghost{
    position:fixed;z-index:999;pointer-events:none;background:var(--ink);color:#fff;
    border-radius:8px;padding:6px 11px;font-size:12px;box-shadow:0 6px 18px rgba(0,0,0,.3);
    transform-origin:0 0;
  }
  .bl-ghost.bl-ghost-blk{background:transparent;padding:0;box-shadow:0 10px 22px rgba(0,0,0,.32)}
  .bl-ghost.bl-trash{opacity:.5;filter:grayscale(1)}
  /* dragged back to the toolbox — the way a block is thrown away in every
     block language a learner has already used */
  body.bl-over-trash .bl-toolbox,
  body.bl-over-trash .bl-flyout{outline:2px dashed #c0392b;outline-offset:-3px;background:#fdecea}
  .blk.bl-dragging{opacity:.3}
  .blk.bl-new{animation:bl-pop .9s ease-out}
  @keyframes bl-pop{
    0%{box-shadow:0 0 0 3px var(--accent)}
    100%{box-shadow:0 0 0 0 rgba(0,0,0,0)}
  }
  /* the selected block, which is what Delete and Ctrl+D act on */
  #blocks-pane .blk.bl-sel > .blk-head{box-shadow:0 0 0 3px var(--accent-deep)}
  .bl-dup{font-size:11px}
  .bl-explain{margin:10px 0}
  .bl-explain-h{font-size:11.5px;color:var(--ink-soft);margin-bottom:5px}

  /* ---- what does this block do? One strip, not a sentence on every block ---- */
  .bl-help{
    flex:none;display:flex;align-items:center;gap:10px;padding:8px 10px;
    border-top:1px solid var(--line);background:var(--panel-2);font-size:12px;
  }
  .bl-help b{flex:none}
  .bl-help-what{color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bl-help-code{
    font-family:var(--font-mono);font-size:11px;background:#22262c;color:#e7ebe4;
    border-radius:6px;padding:3px 8px;flex:none;max-width:45%;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap;
  }
  .bl-help .bl-x{
    margin-left:auto;border:0;background:transparent;color:var(--ink-soft);
    cursor:pointer;font-size:12px;flex:none;
  }

  /* ---- the Arduino code, beside the blocks rather than instead of them ---- */
  .bl-codepane{
    flex:none;width:290px;max-width:46%;display:flex;flex-direction:column;min-height:0;
    border-left:1px solid var(--line);background:var(--panel-2);
  }
  .bl-codepane-head{
    display:flex;align-items:center;gap:8px;padding:7px 10px;flex:none;
    font-size:12px;font-weight:600;border-bottom:1px solid var(--line);
  }
  .bl-codepane-note{font-weight:400;font-size:11px;color:var(--ink-faint)}
  .bl-codepane .bl-x{
    margin-left:auto;border:0;background:transparent;color:var(--ink-soft);
    cursor:pointer;font-size:12px;
  }
  .bl-codepane .peek-code{margin:0;flex:1;min-height:0;overflow:auto;border-radius:0}

  /* ---- starter programs ---- */
  .bl-starters{display:flex;flex-direction:column;gap:7px;max-height:52vh;overflow-y:auto}
  .bl-starter{
    display:flex;align-items:flex-start;gap:11px;text-align:left;cursor:pointer;
    border:1px solid var(--line);border-radius:11px;background:var(--panel-2);
    padding:11px 13px;font:inherit;color:var(--ink);
  }
  .bl-starter:hover{border-color:var(--accent);background:#fff}
  .bl-starter .s-em{font-size:20px;flex:none;line-height:1.2}
  .bl-starter .s-txt{display:flex;flex-direction:column;gap:2px}
  .bl-starter .s-txt i{font-style:normal;font-size:11.5px;color:var(--ink-soft)}

  /* A guided project writes the program; the workspace is for reading it,
     so the toolbox and every editing control are simply not built. */
  .bl-shell.ro .bl-work{cursor:default}

  /* Expanded, and only where there is really room for three columns. */
  @media (min-width: 900px){
    body.code-max .bl-main{flex-direction:row}
    body.code-max .bl-toolbox{
      width:150px;flex-direction:column;overflow-x:hidden;overflow-y:auto;
      border-right:1px solid var(--line);border-bottom:0;padding:8px 6px;
    }
    body.code-max .bl-flyout{
      width:230px;max-height:none;border-right:1px solid var(--line);border-bottom:0;
    }
    body.code-max .bl-flyout-body{flex-direction:column;flex-wrap:nowrap}
    body.code-max .bl-item{flex:0 0 auto}
    body.code-max .bl-stage{flex:1;min-width:0}
  }
  /* Phones and narrow panels: a shorter drawer, and the code pane goes under
     the blocks rather than beside them, so the workspace never becomes a
     column too thin to drop a block into. */
  @media (max-width: 560px){
    .bl-flyout{max-height:40%}
    .bl-stage{flex-direction:column}
    .bl-codepane{
      width:auto;max-width:none;max-height:38%;border-left:0;border-top:1px solid var(--line);
    }
    .bl-help-what{display:none}
  }

  /* A drag has to beat the browser's own gesture. Without this a finger on a
     block scrolls the workspace instead of picking the block up, which is
     the same "drag does not work" from a tablet's point of view. */
  #blocks-pane .blk > .blk-head, #blocks-pane .stack-head, .bl-item{touch-action:none}
  .bl-codepane mark.bl-line{
    background:#F2E70B;color:#22262c;border-radius:3px;padding:0 2px;
  }

  /* The hint and the zoom controls share the bottom edge; in the 295px side
     panel they were on top of each other. */
  .bl-hint{bottom:54px}
  .bl-toolbox::-webkit-scrollbar{height:7px}
  .bl-toolbox::-webkit-scrollbar-thumb{background:#c3ccc0;border-radius:4px}
  .bl-toolbox::-webkit-scrollbar-track{background:transparent}
