  :root {
    --canvas: #E9E7E1;
    --dot: #D3D0C7;
    --panel: #FFFFFF;
    --ink: #23231F;
    --ink-soft: #6E6B62;
    --line: #E2DFD8;
    --accent: #2F6F6A;
    --accent-ink: #FFFFFF;
    --sticky: #FFF4BF;
    --danger: #C0392B;
    --done: #2F9E44;
    --shadow: 0 1px 2px rgba(35,35,31,.10), 0 6px 16px rgba(35,35,31,.08);
    --radius: 10px;
    --topbar-h: 52px;
  }
  * { box-sizing: border-box; }
  html, body { height: 100%; margin: 0; }
  body {
    font: 14px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif;
    color: var(--ink);
    overflow: hidden;
    background: var(--canvas);
  }
  button { font: inherit; color: inherit; cursor: pointer; }
  input, select { font: inherit; }

  /* ---------- Top bar ---------- */
  #topbar {
    position: fixed; inset: 0 0 auto 0; height: var(--topbar-h);
    display: flex; align-items: center; gap: 10px; padding: 0 14px;
    background: var(--panel); border-bottom: 1px solid var(--line); z-index: 50;
  }
  #logo { font-weight: 700; letter-spacing: .2px; white-space: nowrap; }
  #logo small { color: var(--ink-soft); font-weight: 500; }
  .btn {
    border: 1px solid var(--line); background: var(--panel); border-radius: 8px;
    padding: 7px 12px; white-space: nowrap; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  }
  .btn:hover { border-color: var(--ink-soft); }
  .btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
  .btn.primary:hover { filter: brightness(1.08); }
  .icon {                       /* Tabler icons — sprite in index.html, stroke styling lives here */
    width: 16px; height: 16px; flex: none;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  }
  #btn-settings { margin-left: auto; padding: 7px; border: 0; color: var(--ink-soft); }
  #btn-settings:hover { color: var(--ink); background: #F6F5F1; }
  #btn-settings .icon { width: 20px; height: 20px; }

  /* person filter: the topbar button reuses the notes' .assign-menu dropdown, repositioned below the button */
  #filterwrap { position: relative; }
  #filterwrap .assign-menu { top: calc(100% + 6px); right: 0; z-index: 60; }

  #searchwrap { position: relative; flex: 1; max-width: 620px; display: flex; gap: 8px; }
  #scope {
    border: 1px solid var(--line); border-radius: 8px; padding: 7px 8px;
    background: var(--panel); max-width: 190px;
  }
  #search {
    flex: 1; border: 1px solid var(--line); border-radius: 8px; padding: 7px 12px;
    background: var(--panel); min-width: 160px;
  }
  #search:focus, #scope:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
  #results {
    position: absolute; top: calc(100% + 6px); left: 0; right: 0;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
    box-shadow: var(--shadow); max-height: 46vh; overflow: auto; display: none; z-index: 60;
  }
  #results.open { display: block; }
  .result { padding: 9px 12px; cursor: grab; border-bottom: 1px solid var(--line); }
  .result:last-child { border-bottom: 0; }
  .result:hover { background: #F6F5F1; }
  .result .r-title { font-weight: 600; }
  .result .r-path, .result-empty { color: var(--ink-soft); font-size: 12px; }
  .result-empty { padding: 10px 12px; }
  .result.on-map { opacity: .5; }
  .result.on-map .r-title::after { content: " · on map"; color: var(--ink-soft); font-weight: 500; }

  /* ---------- Sidebar (board browser) ---------- */
  #sidebar {
    position: fixed; top: var(--topbar-h); bottom: 0; left: 0; width: 280px;
    background: var(--panel); border-right: 1px solid var(--line);
    transition: transform .18s ease; z-index: 40;
    display: flex; flex-direction: column;
  }
  #sidebar.closed { transform: translateX(-100%); }
  #sb-toggle {                    /* tab on the panel edge; slides along, so it stays reachable when closed */
    position: absolute; left: 100%; top: 50%; translate: 0 -50%;
    width: 22px; height: 64px; padding: 0; cursor: pointer;
    background: var(--panel); border: 1px solid var(--line); border-left: 0;
    border-radius: 0 10px 10px 0; color: var(--ink-soft);
    display: flex; align-items: center; justify-content: center;
  }
  #sb-toggle:hover { color: var(--ink); }
  #sidebar.closed #sb-toggle .icon { transform: rotate(180deg); }
  #sidebar header { padding: 12px; border-bottom: 1px solid var(--line); }
  #sidebar select { width: 100%; padding: 7px 8px; border: 1px solid var(--line); border-radius: 8px; }
  #sidebar .hint { color: var(--ink-soft); font-size: 12px; margin-top: 8px; }
  #boardcards { flex: 1; overflow: auto; padding: 10px 12px; }
  .list-name {
    font-size: 11px; text-transform: uppercase; letter-spacing: .8px;
    color: var(--ink-soft); margin: 14px 0 6px;
  }
  .list-name:first-child { margin-top: 2px; }
  .mini-card {
    background: var(--sticky); border: 1px solid rgba(35,35,31,.12); border-radius: 6px;
    padding: 7px 9px; margin-bottom: 6px; cursor: grab; box-shadow: 0 1px 1px rgba(35,35,31,.08);
  }
  .mini-card:active { cursor: grabbing; }
  .mini-card.on-map { opacity: .45; }

  /* ---------- Canvas ---------- */
  #viewport {
    position: absolute; inset: var(--topbar-h) 0 0 0; overflow: hidden;
    background-image: radial-gradient(var(--dot) 1.2px, transparent 1.2px);
    background-size: 26px 26px; cursor: default; touch-action: none;
  }
  #viewport.panning { cursor: grabbing; }
  #world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }

  /* ---------- Frames ---------- */
  .frame {
    position: absolute; border-radius: 14px;
    border: 2px solid var(--fc);
    background: color-mix(in srgb, var(--fc) 7%, transparent);
    pointer-events: none;       /* body passes clicks through, so overlapped frames stay draggable via their visible heads */
  }
  .frame-head, .frame-resize, .swatches { pointer-events: auto; }
  .frame-head {
    position: absolute; left: -2px; top: -2px; right: -2px; height: 34px;
    display: flex; align-items: center; gap: 8px; padding: 0 10px;
    background: var(--fc); color: #fff; border-radius: 12px 12px 0 0; cursor: grab;
  }
  .frame-head:active { cursor: grabbing; }
  .frame-name { font-weight: 700; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .frame-name[contenteditable="true"] { outline: 1px dashed rgba(255,255,255,.8); border-radius: 4px; padding: 0 4px; }
  .frame-btn {
    background: none; border: 0; color: rgba(255,255,255,.85); padding: 3px 4px;
    border-radius: 4px; display: inline-flex; align-items: center;
  }
  .frame-btn .icon { width: 14px; height: 14px; }
  .frame-btn:hover { background: rgba(255,255,255,.22); color: #fff; }
  .frame-resize {
    position: absolute; right: -4px; bottom: -4px; width: 18px; height: 18px;
    cursor: nwse-resize; border-right: 3px solid var(--fc); border-bottom: 3px solid var(--fc);
    border-radius: 0 0 10px 0;
  }
  /* Eisenhower axes: importance rises upward, urgency rises to the left — so they meet at the bottom-right origin
     and live in the gutter outside the frame, where no note can cover them */
  .frame-axis {
    position: absolute; color: color-mix(in srgb, var(--fc) 65%, var(--ink)); opacity: .6;
    font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  }
  .frame-axis::before, .frame-axis::after { content: ""; position: absolute; }
  .frame-axis::before { background: currentColor; }                                     /* shaft */
  .frame-axis::after { width: 7px; height: 7px; border: solid currentColor; border-width: 1.5px 0 0 1.5px; }   /* arrow head */
  .frame-axis span { display: grid; place-items: center; }
  .frame-axis-y { left: calc(100% + 8px); top: 34px; bottom: 0; width: 30px; }
  .frame-axis-y::before { left: 0; top: 0; bottom: 0; width: 1.5px; }
  .frame-axis-y::after { top: 1px; left: -3px; transform: rotate(45deg); }
  .frame-axis-y span { position: absolute; left: 9px; top: 0; bottom: 0; writing-mode: vertical-rl; transform: rotate(180deg); }
  .frame-axis-x { top: calc(100% + 8px); left: 0; right: 0; height: 30px; }
  .frame-axis-x::before { left: 0; right: 0; top: 0; height: 1.5px; }
  .frame-axis-x::after { top: -3px; left: 1px; transform: rotate(-45deg); }
  .frame-axis-x span { position: absolute; left: 0; right: 0; top: 7px; }

  .swatches {
    position: absolute; top: 36px; right: 6px; display: none; gap: 6px; padding: 8px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow);
  }
  .swatches.open { display: flex; }
  .swatch { width: 20px; height: 20px; border-radius: 50%; border: 2px solid #fff; outline: 1px solid var(--line); }
  .swatch-custom {
    position: relative; display: grid; place-items: center; cursor: pointer;
    background: var(--panel); color: var(--ink-soft);
  }
  .swatch-custom .icon { width: 12px; height: 12px; }
  .swatch-custom:hover { color: var(--ink); }
  .swatch-custom input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; }

  /* ---------- Notes (Trello cards) ---------- */
  .note {
    position: absolute; width: 190px; min-height: 92px;
    background: var(--sticky); border-radius: 4px; padding: 10px 12px 8px;
    box-shadow: var(--shadow); cursor: grab;
    display: flex; flex-direction: column; gap: 6px;
    border-top: 14px solid rgba(35,35,31,.06);
    transition: opacity .15s;
  }
  .note.faded { opacity: .15; }    /* person filter: none of the selected people is assigned */
  .note.tinted { background: color-mix(in srgb, var(--tint) 30%, #FFFDF4); }
  .note:active { cursor: grabbing; }
  .note-title { font-weight: 600; overflow-wrap: anywhere; }
  .note-meta { margin-top: auto; display: flex; align-items: flex-end; gap: 6px; font-size: 11px; color: var(--ink-soft); }
  .note-path { flex: 1; overflow-wrap: anywhere; }
  .avatars { display: flex; }
  .avatar {
    width: 22px; height: 22px; border-radius: 50%; margin-left: -6px;
    background: var(--accent); color: #fff; font-size: 10px; font-weight: 700;
    display: flex; align-items: center; justify-content: center; border: 2px solid #FFFDF4;
  }
  .avatar:first-child { margin-left: 0; }
  .note-x, .note-open, .note-convert, .note-assign, .note-sprint {
    position: absolute; top: -12px; width: 20px; height: 20px; border-radius: 50%;
    border: 1px solid var(--line); background: var(--panel);
    display: none; align-items: center; justify-content: center; padding: 0; text-decoration: none; color: var(--ink);
  }
  .note .icon { width: 12px; height: 12px; }
  .note-x { right: 4px; }
  .note-open, .note-convert { right: 28px; }
  .note-assign { right: 52px; }
  .note-sprint { right: 76px; }
  .note:hover .note-x, .note:hover .note-open, .note:hover .note-convert, .note:hover .note-assign { display: flex; }
  body.sprint .note:hover .note-sprint { display: flex; }      /* only offered once a sprint card is linked */
  .note.in-sprint .note-sprint { display: none !important; }   /* already in — the flag badge says so */
  .note-x:hover { color: var(--danger); border-color: var(--danger); }
  .note-convert:hover, .note-assign:hover, .note-sprint:hover { color: var(--accent); border-color: var(--accent); }

  /* status badges on the note's top-left corner — they stay visible when zoomed out */
  .note-flags { position: absolute; top: -12px; left: -8px; display: flex; gap: 3px; }
  .sprint-badge, .done-badge {
    width: 20px; height: 20px; border-radius: 50%; color: #fff;
    display: none; align-items: center; justify-content: center;
  }
  .sprint-badge { background: var(--accent); }
  .done-badge { background: var(--done); }
  .note.in-sprint { outline: 2px solid var(--accent); outline-offset: 1px; }
  .note.in-sprint .sprint-badge, .note.done .done-badge { display: flex; }
  /* done: the card sits in a Trello list marked 🎊 */
  .note.done .note-title { text-decoration: line-through; text-decoration-color: var(--ink-soft); }

  /* flashed when trying to add a card that's already on the map (box-shadow, so it doesn't clash with the in-sprint outline) */
  .note.flash { animation: note-flash .6s ease 3; }
  @keyframes note-flash {
    30% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent) 55%, transparent), var(--shadow); }
  }

  /* assignments: toggle menu behind the 👤 button, emoji badges in the note footer */
  .assign-menu {
    position: absolute; top: 12px; right: 40px; z-index: 5; display: none;
    flex-direction: column; padding: 4px; min-width: 130px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow);
  }
  .assign-menu.open { display: flex; }
  .assign-menu button { border: 0; background: none; text-align: left; padding: 6px 10px; border-radius: 6px; white-space: nowrap; }
  .assign-menu button:hover { background: #F6F5F1; }
  .assign-menu button.on::after { content: " ✓"; color: var(--accent); font-weight: 700; }
  .badges { display: flex; gap: 2px; font-size: 14px; cursor: default; }

  .note.manual { background: #FFFFFF; border-top-style: dashed; border-top-color: rgba(35,35,31,.25); }
  .note.manual.tinted { background: color-mix(in srgb, var(--tint) 30%, #FFF); }
  .note-title[contenteditable] { outline: 1px dashed var(--ink-soft); border-radius: 4px; padding: 0 2px; }

  /* Zoomed out: title + assignee badges only (menu stays: it's the topbar filter dropdown too) */
  body.mini .note-path, body.mini .avatars, body.mini .note-x, body.mini .note-open, body.mini .note-convert,
  body.mini .note-assign, body.mini .note-sprint, body.mini .note .assign-menu { display: none !important; }
  body.mini .note { min-height: 0; justify-content: center; }
  body.mini .note-title { font-size: 17px; line-height: 1.25; }
  body.mini .badges { font-size: 17px; }
  body.mini .frame-axis { font-size: 17px; }              /* the axes are an orientation aid — keep them readable when zoomed out */
  body.mini .frame-axis-y { width: 40px; }
  body.mini .frame-axis-x { height: 40px; }

  /* ---------- Problems (floating panel on the right): sprint issues + pinboard.json save/load trouble ---------- */
  #problems {
    position: fixed; top: calc(var(--topbar-h) + 12px); right: 12px; width: 300px; max-height: 50vh;
    display: flex; flex-direction: column; overflow: hidden; z-index: 45;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow);
  }
  #problems[hidden] { display: none; }    /* the display:flex rule would otherwise override the hidden attribute */
  #problems header {
    padding: 10px 12px; font-weight: 700; color: var(--danger); border-bottom: 1px solid var(--line);
    display: flex; align-items: center; gap: 6px;
  }
  #problemlist { overflow: auto; }
  .problem { padding: 9px 12px; border-bottom: 1px solid var(--line); font-size: 12px; }
  .problem:last-child { border-bottom: 0; }
  .problem a { display: block; margin-top: 4px; color: var(--accent); text-decoration: none; }
  .problem a:hover { text-decoration: underline; }

  /* ---------- Zoom controls ---------- */
  #zoomctl {
    position: fixed; right: 16px; bottom: 16px; display: flex; flex-direction: column; gap: 6px; z-index: 40;
  }
  #zoomctl .btn { width: 40px; height: 36px; padding: 0; box-shadow: var(--shadow); }
  #zoomlabel { text-align: center; font-size: 11px; color: var(--ink-soft); }

  /* ---------- Modals ---------- */
  .overlay {
    position: fixed; inset: 0; background: rgba(35,35,31,.35); z-index: 90;
    display: none; align-items: center; justify-content: center;
  }
  .overlay.open { display: flex; }
  .modal {
    width: min(560px, 92vw); max-height: 86vh; overflow: auto;
    background: var(--panel); border-radius: 14px; box-shadow: var(--shadow); padding: 22px;
  }
  .modal h2 { margin: 0 0 4px; }
  .modal h3 { margin: 20px 0 8px; font-size: 14px; }
  .modal p { color: var(--ink-soft); margin: 6px 0 14px; }
  .modal a { color: var(--accent); }
  .modal label.field { display: block; margin-bottom: 10px; font-weight: 600; }
  .modal input[type="text"], .modal input[type="password"], .modal select {
    display: block; width: 100%; margin-top: 4px; padding: 8px 10px;
    border: 1px solid var(--line); border-radius: 8px; font-weight: 400; background: var(--panel);
  }
  #boardpick { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; }
  #boardpick label { display: flex; gap: 8px; align-items: center; font-weight: 400; }
  #boardpick:empty::after { content: "Save a valid key and token first, then your boards appear here."; color: var(--ink-soft); grid-column: 1/-1; }
  .modal footer { display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px; }
  #btn-sprint { max-width: 190px; }
  #btn-sprint span { overflow: hidden; text-overflow: ellipsis; }
  #sp-unlink { margin-right: auto; }        /* destructive action sits apart, on the left */

  /* ---------- Sign-in gate ---------- */
  #gate { background: var(--canvas); z-index: 100; }   /* opaque and above every modal: nothing of the board shows before sign-in */
  #gate h2 small { color: var(--ink-soft); font-weight: 500; }
  #gate p { margin: 10px 0 18px; }

  /* ---------- Cleanup modal ---------- */
  .btn.danger { color: var(--danger); border-color: var(--danger); }
  .btn.danger:hover:not(:disabled) { background: var(--danger); color: #fff; }
  .btn.danger.armed { background: var(--danger); color: #fff; }   /* armed: the next click carries the action out */
  .btn[hidden] { display: none; }           /* the display:inline-flex rule would otherwise override the hidden attribute */
  .btn:disabled { opacity: .5; cursor: default; }
  .btn:disabled:hover { border-color: var(--line); }
  #cu-controls { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
  #cu-controls select { display: inline-block; width: auto; margin-top: 0; flex: 1; min-width: 0; }
  #cu-dayswrap { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
  #cu-days { width: 60px; padding: 7px 8px; border: 1px solid var(--line); border-radius: 8px; }
  #cu-toolbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
  #cu-allwrap { display: flex; align-items: center; gap: 8px; }
  #cu-found { color: var(--ink-soft); font-size: 12px; }
  #cu-list { border: 1px solid var(--line); border-radius: 10px; max-height: 44vh; overflow: auto; }
  .cu-row { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--line); cursor: pointer; }
  .cu-row:last-child { border-bottom: 0; }
  .cu-row:hover { background: #F6F5F1; }
  .cu-text { flex: 1; min-width: 0; }
  .cu-title { font-weight: 600; overflow-wrap: anywhere; }
  .cu-meta { color: var(--ink-soft); font-size: 12px; }
  .cu-open { color: var(--ink-soft); text-decoration: none; padding: 2px 6px; border-radius: 6px; }
  .cu-open:hover { color: var(--accent); background: #F0EEE8; }
  .cu-empty { padding: 14px; color: var(--ink-soft); }
  /* floating text preview, shared by cleanup rows (card description) and notes (DOD) */
  #tip {
    position: fixed; z-index: 120; width: 280px; max-height: 40vh; overflow: hidden;
    background: var(--ink); color: #fff; padding: 10px 12px; border-radius: 10px;
    font-size: 12px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere;
    pointer-events: none; box-shadow: var(--shadow);
  }
  #tip[hidden] { display: none; }

  /* ---------- Toast & misc ---------- */
  #toast {
    position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
    background: var(--ink); color: #fff; padding: 9px 16px; border-radius: 999px;
    opacity: 0; transition: opacity .2s; pointer-events: none; z-index: 100; max-width: 80vw;
  }
  #toast.show { opacity: 1; }
  #empty[hidden] { display: none; }
  #empty {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: var(--ink-soft); text-align: center; pointer-events: none;
  }
  #empty div { pointer-events: auto; background: var(--panel); border: 1px solid var(--line);
    border-radius: 14px; padding: 26px 30px; box-shadow: var(--shadow); }
  kbd, code { background: #F0EEE8; border: 1px solid var(--line); border-radius: 4px; padding: 1px 5px; font-size: 12px; }
