  :root{
    --bg:#0b0e14;
    --panel:#141925;
    --panel-2:#1b2233;
    --line:#2a3247;
    --ink:#e9eef8;
    --muted:#8b98b4;
    --accent:#ffb020;
    --accent-2:#35d0a5;
    --cell:#1a2130;
    --cell-ink:#ffffff;
    --cell-line:#2a3247;
    --head:#0f1522;
    --head-ink:#ffb020;
    --radius:10px;
    --gap:6px;
  }
  *{box-sizing:border-box}
  html,body{height:100%}
  body{
    margin:0;background:var(--bg);color:var(--ink);
    font-family:'Inter',"Segoe UI",system-ui,-apple-system,sans-serif;
    overflow:hidden;user-select:none;-webkit-user-select:none;
  }
  button,select,input{font-family:inherit}
  .app{display:flex;flex-direction:column;height:100vh;height:100dvh}

  /* ---------- top chrome ---------- */
  .topbar{
    display:flex;align-items:center;gap:10px;padding:9px 14px;
    background:var(--panel);border-bottom:1px solid var(--line);flex:0 0 auto;
    box-shadow:0 1px 2px rgba(24,32,47,.08);position:relative;z-index:5;
  }
  /* The family's accent hairline across the top of every app chrome. */
  .topbar::after{
    content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
    background:linear-gradient(90deg,var(--accent),color-mix(in srgb,var(--accent) 35%,transparent));
    opacity:.9;
  }
  .brand{display:flex;align-items:center;gap:9px;font-weight:900;letter-spacing:.6px;font-size:13px;
         color:var(--ink);white-space:nowrap}
  .brand svg{width:23px;height:23px;flex:0 0 auto;display:block}
  .brand b{color:var(--accent);font-weight:900}
  .spacer{flex:1}
  .btn{
    background:var(--panel-2);color:var(--ink);border:1px solid var(--line);
    padding:7px 12px;border-radius:10px;font-size:13px;font-weight:600;cursor:pointer;
    display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
    transition:background .12s,border-color .12s,box-shadow .12s;
  }
  .btn:hover{border-color:color-mix(in srgb,var(--ink) 35%,transparent)}
  .btn:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 25%,transparent)}
  .btn.on{background:var(--accent);color:#fff;border-color:var(--accent);
           box-shadow:0 6px 14px -8px color-mix(in srgb,var(--accent) 80%,transparent)}
  .btn.ghost{background:transparent}
  .btn.sm{padding:5px 8px;font-size:12px}
  select.btn{padding:6px 8px}
  .pill{
    font-size:11px;font-weight:700;padding:5px 9px;border-radius:999px;
    background:transparent;color:var(--accent-2);border:1px solid var(--accent-2);white-space:nowrap;
  }
  .pill.bad{color:#e4405f;border-color:#e4405f}

  /* ---------- tabs ---------- */
  .tabbar{
    display:flex;align-items:center;gap:6px;padding:6px 12px;background:var(--panel);
    border-bottom:1px solid var(--line);flex:0 0 auto;overflow-x:auto;scrollbar-width:thin;
  }
  .tab{
    position:relative;padding:7px 14px;border-radius:8px 8px 0 0;background:var(--panel-2);
    border:1px solid var(--line);border-bottom:none;font-size:13px;font-weight:700;
    cursor:pointer;white-space:nowrap;color:var(--muted);display:flex;align-items:center;gap:8px;
  }
  .tab.active{background:var(--bg);color:var(--accent);border-color:var(--accent);box-shadow:inset 0 -3px 0 var(--accent)}
  .tab > span:first-child{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tab .x{opacity:.45;font-size:15px;line-height:1;color:var(--muted);padding:2px 5px;
          border-radius:6px;margin:-2px -6px -2px 0}
  .tab:hover .x,.tab.active .x{opacity:.75}
  .tab .x:hover{opacity:1;color:#fff;background:#e4405f}

  /* ---------- board ---------- */
  .board{flex:1 1 auto;display:flex;flex-direction:column;padding:10px 14px 14px;min-height:0}
  .heading{
    display:flex;align-items:baseline;gap:14px;flex:0 0 auto;padding:2px 2px 10px;
  }
  .heading h1{
    margin:0;font-size:clamp(20px,3.2vh,44px);font-weight:900;letter-spacing:.5px;
    text-transform:uppercase;color:var(--ink);cursor:text;outline:none;
  }
  .heading h1:empty:before{content:"Click to name this board";color:var(--muted)}
  .heading .sub{font-size:clamp(11px,1.5vh,18px);color:var(--muted);font-weight:600;cursor:text;outline:none;min-width:60px}
  .heading .sub:empty:before{content:"subtitle";color:#454f66}
  body.focus .heading .sub:empty:before,body.focus .heading h1:empty:before{content:""}
  .heading .clock{margin-left:auto;font-size:clamp(13px,2vh,26px);font-weight:800;color:var(--accent);font-variant-numeric:tabular-nums}

  .gridwrap{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;gap:var(--gap)}
  /* The shape comes from renderGrid() as --cols and --rows. On a big screen
     the board fills whatever space there is, which is the whole point of a
     board on a wall. The mobile layer at the end of this file changes the
     minimums so it scrolls instead of squeezing. */
  .grid{display:grid;gap:var(--gap);min-height:0;
        grid-template-columns:repeat(var(--cols,5),minmax(0,1fr))}
  .cellgrid{grid-template-rows:repeat(var(--rows,8),minmax(0,1fr))}
  .headrow{flex:0 0 auto}
  .cellgrid{flex:1 1 auto}

  .cell{
    background:var(--cell);border-radius:var(--radius);border:1px solid var(--cell-line);
    display:flex;align-items:stretch;overflow:hidden;
    cursor:grab;position:relative;min-width:0;min-height:0;
  }
  .part{
    display:flex;align-items:center;justify-content:center;padding:5px 7px;
    min-width:0;min-height:0;overflow:hidden;position:relative;
  }
  .part + .part{border-left:1px solid var(--cell-line)}
  .cell .txt{
    width:100%;text-align:center;font-weight:800;line-height:1.08;word-break:break-word;
    color:var(--cell-ink);outline:none;max-height:100%;
  }
  .tag{
    position:absolute;top:3px;right:4px;font-weight:900;line-height:1;
    color:var(--cell-ink);border:2px solid currentColor;border-radius:999px;
    padding:2px 5px;pointer-events:none;opacity:.92;
  }
  .cell.head{background:var(--head);border:1px solid var(--cell-line);cursor:default}
  .cell.head.empty{background:transparent;border-style:dashed;opacity:.5}
  body.light .cell{box-shadow:0 1px 2px rgba(16,24,40,.07)}
  body.light .cell.head.empty{box-shadow:none}
  body.light .cell.sel{box-shadow:0 0 0 5px rgba(37,99,235,.16)}
  .mark{width:26px;padding:5px 0;text-align:center;font-size:14px;line-height:1}
  .tagin{width:54px;background:var(--panel-2);border:1px solid var(--line);color:var(--ink);
         border-radius:8px;padding:6px 8px;font-size:13px;font-weight:800;text-align:center}
  /* template gallery */
  #dlgTpl{width:min(820px,95vw)}
  .tpl{border:1px solid var(--line);border-radius:10px;padding:11px 13px;cursor:pointer;background:var(--panel-2);margin-bottom:9px}
  .tpl:hover{border-color:var(--accent);background:var(--panel)}
  .tpl .tn{font-size:14px;font-weight:800;color:var(--ink)}
  .tpl .td{font-size:12px;color:var(--muted);margin:2px 0 7px}
  .chips{display:flex;flex-wrap:wrap;gap:5px}
  .chip{font-size:11px;font-weight:800;padding:3px 7px;border-radius:5px;
        background:var(--cell);border:1px solid var(--cell-line);white-space:nowrap}
  .chip b{font-weight:900;opacity:.65;margin-left:3px}
  .cell.head .txt{color:var(--head-ink);text-transform:uppercase;letter-spacing:1px}
  .part.sel{outline:3px solid var(--accent);outline-offset:-2px;z-index:2}
  .cell.sel{box-shadow:0 0 0 5px rgba(255,176,32,.14)}
  .cell.editing{cursor:text}
  .cell.dragging{opacity:.35}
  .cell.drop{outline:3px dashed var(--accent-2);outline-offset:-2px}
  .cell.empty .txt:before{content:"";}

  /* ---------- bottom inspector ---------- */
  .inspector{
    flex:0 0 auto;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    padding:8px 12px;background:var(--panel);border-top:1px solid var(--line);
  }
  .grp{display:flex;align-items:center;gap:6px}
  .grp .lbl{font-size:11px;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.8px;margin-right:2px}
  .sw{width:22px;height:22px;border-radius:6px;border:1px solid rgba(128,140,160,.5);cursor:pointer;padding:0}
  .sw:hover{transform:scale(1.12)}
  .sw.none{background:
    linear-gradient(45deg,#2a3247 25%,transparent 25%,transparent 75%,#2a3247 75%),
    linear-gradient(45deg,#2a3247 25%,#141925 25%,#141925 75%,#2a3247 75%);
    background-size:10px 10px;background-position:0 0,5px 5px}
  .hint{font-size:12px;color:var(--muted)}

  /* ---------- dialogs ---------- */
  dialog{
    border:1px solid var(--line);background:var(--panel);color:var(--ink);
    border-radius:14px;padding:0;width:min(520px,92vw);box-shadow:0 30px 80px rgba(0,0,0,.6);
  }
  dialog::backdrop{background:rgba(4,6,12,.7)}
  .dlg-h{padding:14px 18px;border-bottom:1px solid var(--line);font-weight:800;font-size:15px}
  .dlg-b{padding:16px 18px;display:flex;flex-direction:column;gap:14px}
  .dlg-f{padding:12px 18px;border-top:1px solid var(--line);display:flex;justify-content:flex-end;gap:8px}
  .row{display:flex;align-items:center;gap:10px;justify-content:space-between}
  .row label{font-size:13px;font-weight:600;color:var(--muted)}
  .num{width:90px;background:var(--panel-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:7px 9px;font-size:14px}
  .full{width:100%;background:var(--panel-2);border:1px solid var(--line);color:var(--ink);border-radius:8px;padding:8px 10px;font-size:14px}
  .help{font-size:12px;color:var(--muted);line-height:1.5}
  kbd{background:var(--panel-2);border:1px solid var(--line);border-bottom-width:2px;border-radius:5px;padding:1px 5px;font-size:11px;font-family:inherit}

  /* ---------- focus (TV) mode ---------- */
  body.focus .topbar,body.focus .inspector{display:none}
  body.focus .tabbar{background:transparent;border-bottom:none;justify-content:center}
  body.focus .tab .x{display:none}
  body.focus .tabbar.single{display:none}
  body.focus .tabbar .tab:last-child{display:none}
  body.focus .heading h1{font-size:clamp(26px,4.4vh,62px)}
  body.focus .heading{padding-bottom:12px}
  body.focus .board{padding:14px 22px 22px}
  #exitFocus{display:none;position:fixed;right:14px;top:10px;z-index:50;opacity:.25}
  #exitFocus:hover{opacity:1}
  body.focus #exitFocus{display:inline-flex}
  .toast{
    position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(20px);
    background:var(--accent);color:#1a1200;font-weight:800;font-size:13px;padding:10px 16px;
    border-radius:999px;opacity:0;transition:.25s;pointer-events:none;z-index:99;
  }
  .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

  /* ---------- theme gallery ---------- */
  #dlgTheme{width:min(780px,95vw)}
  .themes{display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr));gap:10px}
  .scroller{max-height:58vh;overflow:auto;padding-right:6px}
  .grouplbl{font-size:11px;font-weight:800;letter-spacing:1px;text-transform:uppercase;
            color:var(--muted);margin:14px 2px 6px}
  .grouplbl:first-child{margin-top:0}
  .theme{border:2px solid var(--line);border-radius:10px;cursor:pointer;overflow:hidden;background:var(--panel-2)}
  .theme:hover{border-color:var(--muted)}
  .theme.on{border-color:var(--accent);box-shadow:0 0 0 3px rgba(255,176,32,.18)}
  .tp{padding:8px}
  .tp .h{height:14px;border-radius:3px;margin-bottom:5px;display:flex;align-items:center;
         justify-content:center;font-size:8px;font-weight:800;letter-spacing:.6px}
  .tp .r{display:grid;grid-template-columns:1fr 1fr 1fr;gap:4px}
  .tp .r i{height:22px;border-radius:4px;display:flex;align-items:center;justify-content:center;
           font-size:10px;font-weight:800;font-style:normal}
  .theme .nm{padding:6px 8px;font-size:11px;font-weight:700;border-top:1px solid var(--line);
             color:var(--ink);background:var(--panel);text-align:center}
  .step{display:flex;gap:11px;align-items:flex-start}
  .step .n{flex:0 0 24px;height:24px;border-radius:50%;background:var(--accent);color:#1a1200;
           font-weight:900;font-size:12px;display:flex;align-items:center;justify-content:center}
  .step .tx{font-size:13px;line-height:1.55;color:var(--ink)}
  .step .tx b{color:var(--accent)}

  /* ================================================================
     WEB APP CHROME
     Added for the hosted app. Everything above this line is the
     engine's own CSS, unchanged, and the 25 color schemes still drive
     every pixel below the chrome bar. The chrome bar itself is fixed
     brand: Board White surface, Deep Ink text, Marker Red accent.
     ================================================================ */
  :root{
    --msb-red:#C81E1E;
    --msb-ink:#14171D;
    --msb-white:#F7F6F0;
    --msb-rule:#d9d7cd;
  }

  .chrome{
    display:flex;align-items:center;gap:9px;padding:7px 12px;flex:0 0 auto;
    background:var(--msb-white);color:var(--msb-ink);border-bottom:1px solid var(--msb-rule);
    box-shadow:inset 0 -3px 0 var(--msb-red);
    font-family:"Segoe UI",system-ui,-apple-system,sans-serif;
  }
  .chrome .mkbtn{
    background:#fff;color:var(--msb-ink);border:1px solid var(--msb-rule);
    padding:6px 10px;border-radius:8px;font-size:12px;font-weight:700;cursor:pointer;
    display:inline-flex;align-items:center;gap:6px;white-space:nowrap;font-family:inherit;
  }
  .chrome .mkbtn:hover{background:#eceae2;border-color:#b9b6a9}
  .chrome .mkbtn.primary{background:var(--msb-red);border-color:var(--msb-red);color:#fff}
  .chrome .mkbtn.primary:hover{background:#a81818}
  .chrome .mkbtn.on{background:var(--msb-ink);border-color:var(--msb-ink);color:var(--msb-white)}
  .chrome a.mkbtn{text-decoration:none}
  .chrome .spacer{flex:1}
  .chromemark{display:flex;align-items:center;gap:8px;flex:0 0 auto;
              color:inherit;text-decoration:none}
  a.chromemark:hover .wm{opacity:.75}
  .chromemark svg{width:22px;height:22px;display:block}
  .chromemark .wm{font-weight:900;font-size:12px;letter-spacing:.6px;white-space:nowrap;
                  font-family:"Arial Black","Segoe UI Black",Impact,system-ui,sans-serif}
  .chromemark .wm i{color:var(--msb-red);font-style:normal}
  .chromedivide{width:1px;height:22px;background:var(--msb-rule);flex:0 0 auto}
  #boardTitle{
    font-size:14px;font-weight:800;color:var(--msb-ink);outline:none;border-radius:6px;
    padding:4px 7px;max-width:34vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    border:1px solid transparent;min-width:40px;
  }
  #boardTitle[contenteditable="true"]{cursor:text}
  #boardTitle[contenteditable="true"]:hover{border-color:var(--msb-rule);background:#fff}
  #boardTitle[contenteditable="true"]:focus{border-color:var(--msb-red);background:#fff}
  #boardTitle:empty:before{content:"Name this board";opacity:.45}

  .status{
    display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;
    padding:4px 10px;border-radius:999px;background:#fff;border:1px solid var(--msb-rule);
    color:#5c5f66;white-space:nowrap;
  }
  .status .dot{width:8px;height:8px;border-radius:50%;background:#a8a59a;flex:0 0 auto}
  .status.saved .dot{background:#1D7A44}
  .status.saving .dot{background:#B4780E;animation:msbpulse 1s infinite}
  .status.offline{color:#7f1414;border-color:#e2b4b4;background:#fdf1f1}
  .status.offline .dot{background:var(--msb-red);animation:msbpulse 1.2s infinite}
  .status.live .dot{background:#1D7A44;animation:msbpulse 2.4s infinite}
  @keyframes msbpulse{0%,100%{opacity:1}50%{opacity:.25}}

  /* quiet notice strip under the chrome bar */
  .notices{flex:0 0 auto;display:none;flex-direction:column;background:#fffdf7;
           border-bottom:1px solid var(--msb-rule);
           font-family:"Segoe UI",system-ui,sans-serif}
  .notices.show{display:flex}
  .notice{display:flex;align-items:center;gap:9px;padding:7px 14px;font-size:12.5px;
          color:#3b3d42;border-top:1px solid #ece9df;line-height:1.45}
  .notice:first-child{border-top:none}
  .notice.warn{background:#fdf1f1;color:#5c1212}
  .notice.warn b{color:var(--msb-red)}
  .notice .nx{margin-left:auto;cursor:pointer;opacity:.5;font-weight:900;padding:0 4px;flex:0 0 auto}
  .notice .nx:hover{opacity:1}
  .notice code{background:#fff;border:1px solid var(--msb-rule);border-radius:5px;padding:2px 6px;
               font-family:Consolas,monospace;max-width:46vw;overflow:hidden;text-overflow:ellipsis;
               white-space:nowrap;display:inline-block;vertical-align:bottom}

  /* ---------- history drawer ---------- */
  .drawer{
    position:fixed;top:0;right:0;bottom:0;width:min(400px,94vw);z-index:60;
    background:var(--panel);border-left:1px solid var(--line);color:var(--ink);
    display:flex;flex-direction:column;transform:translateX(102%);transition:transform .18s ease;
    box-shadow:-18px 0 50px rgba(0,0,0,.35);
  }
  .drawer.open{transform:none}
  .drawer-h{padding:13px 16px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
  .drawer-h .t{font-weight:800;font-size:14px}
  .drawer-h .spacer{flex:1}
  .drawer-b{flex:1 1 auto;overflow:auto;padding:10px 12px}
  .drawer-f{padding:11px 14px;border-top:1px solid var(--line);font-size:12px;color:var(--muted);line-height:1.5}
  .rev{border:1px solid var(--line);background:var(--panel-2);border-radius:10px;padding:9px 11px;
       margin-bottom:8px;cursor:pointer}
  .rev:hover{border-color:var(--accent)}
  .rev.on{border-color:var(--accent);box-shadow:0 0 0 2px rgba(200,30,30,.18)}
  .rev .rh{display:flex;align-items:baseline;gap:8px}
  .rev .rv{font-weight:900;font-size:12px;color:var(--accent)}
  .rev .rt{font-size:12px;font-weight:700}
  .rev .rw{font-size:11.5px;color:var(--muted);margin-top:2px}
  .rev .rs{display:flex;flex-wrap:wrap;gap:5px;margin-top:7px}
  .rev .rs span{font-size:10.5px;font-weight:800;padding:2px 6px;border-radius:5px;
                background:var(--cell);border:1px solid var(--cell-line)}

  .previewbar{
    flex:0 0 auto;display:none;align-items:center;gap:10px;padding:8px 14px;
    background:var(--msb-red);color:#fff;font-size:13px;font-weight:700;
    font-family:"Segoe UI",system-ui,sans-serif;
  }
  body.previewing .previewbar{display:flex}
  .previewbar .spacer{flex:1}
  .previewbar button{background:#fff;color:var(--msb-red);border:0;border-radius:7px;
                     padding:6px 11px;font-weight:800;font-size:12px;cursor:pointer;font-family:inherit}
  .previewbar button.ghost{background:rgba(255,255,255,.16);color:#fff}

  /* ---------- share and people dialog ---------- */
  #dlgShare{width:min(620px,94vw)}
  #dlgShare .dlg-b{max-height:72vh;overflow:auto}
  .vis{display:flex;align-items:flex-start;gap:9px;border:1px solid var(--line);border-radius:10px;
       padding:9px 11px;background:var(--panel-2);cursor:pointer}
  .vis.on{border-color:var(--accent)}
  .vis input{margin-top:3px;width:17px;height:17px;flex:0 0 auto}
  .vis .vt{font-size:13px;font-weight:800}
  .vis .vd{font-size:12px;color:var(--muted);margin-top:2px;line-height:1.45}
  .linkrow{display:flex;gap:7px;align-items:center}
  .linkrow input{flex:1 1 auto;min-width:0}
  .mem{display:flex;align-items:center;gap:9px;padding:8px 0;border-top:1px solid var(--line)}
  .mem:first-child{border-top:none}
  .mem .mi{flex:1 1 auto;min-width:0}
  .mem .mn{font-size:13px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mem .me{font-size:11.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mem .mo{font-size:11px;font-weight:800;color:var(--accent-2)}
  .upsell{font-size:12.5px;line-height:1.5;color:var(--ink);background:var(--panel-2);
          border:1px solid var(--accent);border-radius:9px;padding:9px 11px}
  .sect{font-size:11px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;color:var(--muted)}

  /* TV mode hides the app chrome too, the same way the engine hides its own */
  body.focus .chrome,body.focus .notices,body.focus .previewbar{display:none}
  body.focus .drawer{display:none}
  /* viewer mode: nothing that changes data is on screen at all */
  body.readonly .inspector,body.readonly .enginebar{display:none}
  body.readonly .cell{cursor:default}
  body.readonly .heading h1,body.readonly .heading .sub{cursor:default}
  body.readonly .heading h1:empty:before,body.readonly .heading .sub:empty:before{content:""}
  body.readonly .tab .x{display:none}
  /* in TV mode the engine hides the last tab, which is its add button.
     A viewer has no add button, so its last tab is a real one: keep it. */
  body.readonly.focus .tabbar .tab:last-child{display:flex}
  /* a history preview is read only too: put the editing chrome away */
  body.previewing .inspector,body.previewing .enginebar{display:none}

  /* a hidden button stays hidden: .btn and .mkbtn both set display, which
     would otherwise beat the browser's own rule for the hidden attribute */
  .btn[hidden],.chrome .mkbtn[hidden],.previewbar button[hidden],
  .pill[hidden],.chromemark[hidden]{display:none}

/* ==================================================================
   THE DEMO BAR
   Shown only on /demo. A person who lands on a board full of someone
   else's deals needs two facts immediately: this is a demo, and it is
   safe to touch. Everything else on the page is the real app.
   ================================================================== */
.demobar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 14px; margin: 0;
  background: linear-gradient(180deg, #FFF8E6, #FFF2D4);
  border-bottom: 1px solid #F0D79A;
  color: #4A3A12; font-size: 13.5px; line-height: 1.4;
}
.demobar[hidden] { display: none; }
.demodot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: #E8A317; box-shadow: 0 0 0 3px rgba(232,163,23,.22);
  animation: demopulse 2.2s ease-in-out infinite;
}
@keyframes demopulse { 50% { opacity: .35; } }
.demotext { flex: 1 1 auto; min-width: 200px; }
.demotext b { font-weight: 700; }
.demobtn {
  flex: none; display: inline-flex; align-items: center; height: 30px; padding: 0 13px;
  border-radius: 4px; border: 1px solid #DDBE7A; background: #fff; color: #4A3A12;
  font-size: 13px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.demobtn:hover { border-color: #A8812A; }
.demobtn.primary { background: #C81E1E; border-color: #C81E1E; color: #fff; }
.demobtn.primary:hover { background: #A81818; border-color: #A81818; }
@media (max-width: 620px) {
  .demotext { font-size: 12.5px; }
  .demobar { gap: 8px; padding: 8px 12px; }
}
.demoshort { display: none; }
/* TV mode and full screen hide the chrome; the bar goes with it. */
body.focus .demobar { display: none; }
@media (prefers-reduced-motion: reduce) { .demodot { animation: none; } }


/* ==================================================================
   PHONES AND SMALL TABLETS
   ------------------------------------------------------------------
   This app was built for a television on a wall, and every layout
   decision above says so: the board stretches to fill the screen, and
   the text shrinks to whatever fits. On a phone that logic runs off a
   cliff. Seven columns across 390 points gives each one about fifty,
   the autofit bottoms out at its 9px floor, and the board turns into
   grey lines. The chrome and the toolbar, both single unwrapped rows,
   simply run off the right edge with no way to reach what is out
   there.

   So below 820px the board stops trying to fit and starts to scroll.
   Columns get a real minimum width and rows a real minimum height, so
   the text has room to be read, and you swipe across a board that is
   wider than the phone, which is what every spreadsheet on a phone
   does. The headings stay put at the top and the first column stays
   put at the left, so you never lose track of which row is which.
   Every strip of controls scrolls sideways instead of hiding half of
   itself.
   ================================================================== */

@media (max-width: 820px) {

  /* ---- the board scrolls instead of squeezing ---- */
  .gridwrap {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    display: block;                 /* flex children would stretch to the wrap */
    /* Columns land where the pinned one ends, instead of stopping halfway and
       leaving a sliver of the next name sitting beside it. Proximity rather
       than mandatory, so a deliberate small nudge is still allowed and
       dragging a square across the board is not fought by the scroller. */
    scroll-snap-type: x proximity;
    scroll-padding-left: calc(124px + var(--gap));
  }
  .cellgrid .cell:not(.c0), .headrow .cell:not(.c0) { scroll-snap-align: start; }
  .grid { grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr)); }
  .cellgrid {
    grid-template-rows: repeat(var(--rows, 8), minmax(58px, auto));
    margin-top: var(--gap);
  }
  /* Both grids have to be the same width or the columns stop lining up.
     max-content let the 1fr columns grow to fit the longest name, which on a
     seven column board meant two and a half columns on screen. The width is
     stated instead: cols x 124px plus the gaps between them, as a floor. A
     wide board passes the viewport and scrolls; a three column board is under
     it, so the 1fr shares out the slack and it still fills the screen. */
  .headrow, .cellgrid {
    min-width: calc(var(--cols, 5) * 124px + (var(--cols, 5) - 1) * var(--gap));
  }

  /* The headings stay on screen while the rows scroll under them, and the
     first column stays while the rest scrolls sideways, so a row never
     becomes anonymous halfway across a wide board.

     Both need to paint the gap beside them as well as their own box. The
     gap between cells is board background, and a cell scrolling past shows
     through it: without this you see slivers of the Lender column sitting
     next to a pinned name. A pseudo-element cannot do it, because .cell
     clips to its own box; a shadow is not clipped, so the gap is painted by
     an offset solid shadow, with one more pixel of rule behind it. */
  .headrow { position: sticky; top: 0; z-index: 4; background: var(--bg);
             box-shadow: 0 var(--gap) 0 var(--bg); }
  .headrow .cell { background: var(--head); }

  .cell.c0 { position: sticky; left: 0; z-index: 3;
             box-shadow: var(--gap) 0 0 0 var(--bg),
                         calc(var(--gap) + 1px) 0 0 0 var(--cell-line); }
  .headrow .cell.c0 { z-index: 5;
             box-shadow: var(--gap) 0 0 0 var(--bg),
                         calc(var(--gap) + 1px) 0 0 0 var(--cell-line); }

  /* ---- every strip of controls scrolls rather than hiding itself ---- */
  .chrome, .topbar, .tabbar, .inspector {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .chrome::-webkit-scrollbar, .topbar::-webkit-scrollbar,
  .tabbar::-webkit-scrollbar, .inspector::-webkit-scrollbar { display: none; }
  .chrome > *, .topbar > *, .inspector > * { flex: 0 0 auto; }
  .chrome .spacer { display: none; }   /* a flex spacer in a scroller is dead space */

  .chrome { gap: 7px; padding: 6px 10px; }
  .chrome .mkbtn { padding: 6px 9px; font-size: 12px; }
  .chrome .wm { font-size: 13px; }
  #boardTitle { max-width: 36vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* The inspector was the worst of it: flex-wrap turned it into eight stacked
     rows eating half the screen. One scrolling strip instead. */
  .inspector { gap: 10px; padding: 7px 10px; }
  .inspector .hint { display: none; }
  .grp { flex: 0 0 auto; }
  .sw { width: 26px; height: 26px; }   /* a 22px target is too small for a thumb */
  .sw:hover { transform: none; }

  /* ---- the board's own heading ---- */
  .board { padding: 8px 10px 10px; }
  .heading { gap: 8px; padding-bottom: 7px; flex-wrap: wrap; }
  .heading h1 { font-size: clamp(18px, 5.2vw, 26px); letter-spacing: .3px; }
  .heading .sub { font-size: 12px; }
  .heading .clock { font-size: 12.5px; margin-left: auto; }

  /* ---- the demo bar, two lines at most ---- */
  .demobar { gap: 7px; padding: 6px 10px; font-size: 12.5px; }
  .demotext { min-width: 0; flex: 1 1 auto; }   /* beside the buttons, not above */
  .demobtn { height: 27px; padding: 0 10px; font-size: 12px; }

  /* The placeholder that prompts you to name the subtitle is an editing hint
     for a mouse. On a phone it just reads as the word "subtitle" sitting under
     the title of a board that does not have one. */
  .heading .sub:empty { display: none; }

  /* The autofit shrinks text until it fits, but break-word let it split a name
     down the middle and call that a fit: "Washbur / n". Breaking only between
     words means an oversized name overflows the width instead, and the width
     is what the loop measures, so it keeps shrinking until the name is whole.
     break-word is no good here: it breaks the name and the overflow goes
     away, so the loop sees a fit and stops at "Washbur / n". */
  .cell .txt { word-break: normal; overflow-wrap: normal; }
}

/* Narrow phones: the same, with less of everything. */
@media (max-width: 460px) {
  .headrow, .cellgrid {
    min-width: calc(var(--cols, 5) * 112px + (var(--cols, 5) - 1) * var(--gap));
  }
  .gridwrap { scroll-padding-left: calc(112px + var(--gap)); }
  .cellgrid { grid-template-rows: repeat(var(--rows, 8), minmax(52px, auto)); }
  .chrome .mkbtn { padding: 5px 8px; font-size: 11.5px; }
  .demotext { font-size: 12px; }
  /* At this width the bar gets one line, so it keeps the sentence that matters
     and drops the rest. "Back to the site" becomes "Exit" for the same reason. */
  .demotext .demolong, .demotext .demomid { display: none; }
  .demolong2 { display: none; }
  .demoshort { display: inline; }
}
