  :root{
    --ink:#1b1f23;
    --paper:#fafafa;
    --panel:#ffffff;
    --line:#d7dbe0;
    --line-strong:#9aa2ab;
    --accent:#2c5f6f;
    --accent-dark:#1c4652;
    --accent-soft:#e5eef0;
    --warn:#8a4b17;
    --warn-bg:#fbeee0;
    --mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
    --sans: Arial, Helvetica, "Segoe UI", sans-serif;
  }
  *{box-sizing:border-box;}
  html,body{margin:0;padding:0;}
  body{
    background:var(--paper);
    color:var(--ink);
    font-family:var(--sans);
    line-height:1.4;
  }
  #app{
    max-width:1180px;
    margin:0 auto;
    padding:22px 20px 60px;
  }
  header.top{
    display:flex;
    align-items:baseline;
    justify-content:space-between;
    flex-wrap:wrap;
    gap:8px;
    border-bottom:3px solid var(--ink);
    padding-bottom:12px;
    margin-bottom:22px;
  }
  header.top h1{
    font-size:1.5rem;
    margin:0;
    letter-spacing:.2px;
  }
  header.top .sub{
    font-size:.85rem;
    color:#555;
  }
  .layout{
    display:grid;
    grid-template-columns: minmax(340px, 1fr) 420px;
    gap:28px;
    align-items:start;
  }
  @media (max-width: 880px){
    .layout{grid-template-columns:1fr;}
  }
  .panel{
    background:var(--panel);
    border:1px solid var(--line);
    border-radius:8px;
    padding:18px 20px;
    margin-bottom:20px;
  }
  .panel h2{
    font-size:1rem;
    margin:0 0 14px;
    text-transform:uppercase;
    letter-spacing:.06em;
    color:var(--accent-dark);
  }
  .field{
    margin-bottom:14px;
  }
  .field label{
    display:block;
    font-size:.8rem;
    font-weight:700;
    margin-bottom:4px;
    color:#333;
  }
  .default-check{
    display:flex;
    align-items:center;
    gap:6px;
    margin-top:8px;
    font-size:.78rem;
    color:#555;
    cursor:pointer;
    user-select:none;
  }
  .default-check input[type="checkbox"]{
    width:14px;
    height:14px;
    accent-color:var(--accent);
    cursor:pointer;
  }
  .combo{
    position:relative;
  }
  .combo input[type="text"]{
    width:100%;
    padding:9px 10px;
    font-size:.95rem;
    border:1px solid var(--line-strong);
    border-radius:5px;
    font-family:var(--sans);
  }
  .combo input[type="text"]:focus{
    outline:2px solid var(--accent);
    outline-offset:1px;
  }
  .combo .picked{
    margin-top:6px;
    font-size:.8rem;
    color:var(--accent-dark);
    min-height:1.1em;
  }
  .combo .picked b{color:var(--ink);}
  .combo-list{
    position:absolute;
    z-index:20;
    top:100%;
    left:0;
    right:0;
    background:#fff;
    border:1px solid var(--line-strong);
    border-top:none;
    max-height:260px;
    overflow-y:auto;
    border-radius:0 0 5px 5px;
    box-shadow:0 6px 14px rgba(0,0,0,.12);
    display:none;
  }
  .combo-list.open{display:block;}
  .combo-list div{
    padding:7px 10px;
    cursor:pointer;
    font-size:.87rem;
    border-bottom:1px solid #f0f0f0;
  }
  .combo-list div:last-child{border-bottom:none;}
  .combo-list div:hover,
  .combo-list div.active{
    background:var(--accent-soft);
  }
  .combo-list div .sym{
    color:var(--accent-dark);
    font-weight:700;
    font-family:var(--mono);
    font-size:.78rem;
  }
  .combo-list .empty{
    color:#888;
    font-style:italic;
    cursor:default;
  }
  .row-inline{
    display:flex;
    gap:10px;
    align-items:flex-end;
    flex-wrap:wrap;
  }
  .row-inline .field{flex:1;min-width:160px;margin-bottom:0;}
  button{
    font-family:var(--sans);
    cursor:pointer;
  }
  .btn{
    background:var(--accent);
    color:#fff;
    border:none;
    padding:9px 14px;
    border-radius:5px;
    font-size:.85rem;
    font-weight:700;
  }
  .btn:hover{background:var(--accent-dark);}
  .btn:disabled{background:#b7bec3;cursor:not-allowed;}
  .btn.secondary{
    background:#fff;
    color:var(--accent-dark);
    border:1px solid var(--accent);
  }
  .btn.secondary:hover{background:var(--accent-soft);}
  .btn.small{padding:5px 9px;font-size:.75rem;}
  .btn.ghost{
    background:transparent;
    color:#666;
    border:1px solid var(--line-strong);
  }
  .btn.ghost:hover{background:#f0f0f0;}
  .swap-btn{
    width:100%;
    text-align:center;
    padding:6px;
    font-size:.75rem;
    background:#fff;
    border:1px dashed var(--line-strong);
    border-radius:5px;
    color:#555;
    margin:-2px 0 14px;
  }
  .swap-btn:hover{background:#f0f0f0;}
  .qty-input{
    width:70px;
    padding:9px 8px;
    font-size:.95rem;
    border:1px solid var(--line-strong);
    border-radius:5px;
  }
  .actions{
    display:flex;
    gap:10px;
    flex-wrap:wrap;
    margin-top:16px;
  }
  .queue-list{
    list-style:none;
    margin:0 0 14px;
    padding:0;
    border-top:1px solid var(--line);
  }
  .queue-list li{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:10px;
    padding:9px 2px;
    border-bottom:1px solid var(--line);
    font-size:.85rem;
  }
  .queue-list .desc{flex:1;}
  .queue-list .desc .arrow{color:var(--accent);margin:0 4px;}
  .queue-list .copies{
    font-family:var(--mono);
    font-size:.78rem;
    background:var(--accent-soft);
    color:var(--accent-dark);
    padding:2px 7px;
    border-radius:10px;
    white-space:nowrap;
  }
  .queue-empty{
    color:#888;
    font-size:.85rem;
    font-style:italic;
    padding:10px 2px;
  }
  .queue-summary{
    font-size:.82rem;
    color:#444;
    margin-bottom:10px;
  }
  .remove-x{
    background:none;
    border:none;
    color:#a33;
    font-size:1rem;
    line-height:1;
    padding:2px 6px;
  }
  .remove-x:hover{color:#700;}
  .status-msg{
    font-size:.8rem;
    padding:8px 10px;
    border-radius:5px;
    margin-top:10px;
    display:none;
  }
  .status-msg.show{display:block;}
  .status-msg.ok{background:#e4f3e6;color:#245c2c;}
  .status-msg.err{background:var(--warn-bg);color:var(--warn);}
  details.roster-update{
    margin-top:4px;
  }
  details.roster-update summary{
    cursor:pointer;
    font-size:.82rem;
    color:var(--accent-dark);
    font-weight:700;
    padding:4px 0;
  }
  details.roster-update textarea{
    width:100%;
    height:120px;
    font-family:var(--mono);
    font-size:.72rem;
    border:1px solid var(--line-strong);
    border-radius:5px;
    padding:8px;
    margin:10px 0;
    resize:vertical;
  }
  .roster-help{
    font-size:.76rem;
    color:#666;
    margin:6px 0 10px;
  }
  .roster-count{
    font-size:.78rem;
    color:#666;
    margin-top:8px;
  }
  /* ---------- Live preview ---------- */
  .preview-wrap{
    position:sticky;
    top:20px;
  }
  .preview-frame{
    display:flex;
    justify-content:center;
    padding:16px 10px;
    background:#eef0f2;
    border:1px solid var(--line);
    border-radius:8px;
  }
  .label{
    background:#fff;
    border:2.1pt solid #000;
    color:#000;
    display:flex;
    flex-direction:column;
    box-sizing:border-box;
    /* Deliberately no fixed height + overflow:hidden here. A fixed box that
       clips would silently drop the bottom line (e.g. "Hub: xxx") for any
       institution name long enough to wrap further than expected — exactly
       what happened. Instead each label has a min-height target and grows
       taller if it truly needs to, so content can never be cut off. */
  }
  .label--preview{
    width:100%;
    max-width:372px;
    min-height:189px;
    padding:8px 13px 11px;
  }
  .label--print{
    width:3.7in;
    min-height:2in;
    padding:0.09in 0.13in 0.12in;
  }
  .top-row{
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    gap:6px;
  }
  .from-block{
    font-family:var(--sans);
    text-align:left;
    flex:1 1 auto;
    min-width:0;
  }
  .label--preview .from-block{font-size:11.5px; line-height:1.34;}
  .label--print .from-block{font-size:6.6pt; line-height:1.34;}
  .from-block div{overflow-wrap:break-word;}
  .date-stamp{
    font-family:var(--sans);
    text-align:right;
    white-space:nowrap;
    flex:0 0 auto;
    color:#333;
    line-height:1.34;
  }
  .label--preview .date-stamp{font-size:7px;}
  .label--print .date-stamp{font-size:5pt;}
  .to-block{
    font-family:Georgia,"Times New Roman",Times,serif;
    font-weight:700;
    text-align:center;
  }
  .label--preview .to-block{font-size:21px; line-height:1.56; margin-top:10px;}
  .label--print .to-block{font-size:13pt; line-height:1.56; margin-top:0.1in;}
  .empty-preview{
    color:#888;
    font-size:.85rem;
    text-align:center;
    padding:40px 14px;
  }
  footer.note{
    font-size:.78rem;
    color:#777;
    margin-top:30px;
    border-top:1px solid var(--line);
    padding-top:14px;
  }

  /* ---------- Print ---------- */
  /* printArea stays in normal layout flow (off-screen) at all times so its
     contents have real, measurable dimensions before window.print() is
     called — a display:none area can't be measured for the text auto-fit.
     Deliberately position:absolute, not position:fixed — fixed-positioned
     elements are unreliable in print output in some browsers (Chrome in
     particular has a long history of dropping or mis-flowing them across
     print pages), which is what was causing the print preview to come out
     blank even though the content was there in the DOM. */
  #printArea{
    position:absolute;
    top:0;
    left:-10000px;
    margin:0;
  }
  @media print{
    /* #app{display:none;} alone only hides this plugin's own panel — it
       has no idea the page also has a WordPress theme header, nav,
       search bar, and footer wrapped around it, and those were printing
       too, pushing an 8-label sheet onto a second page. This hides
       EVERYTHING on the page and then makes only the actual label sheet
       (and its contents) visible again, regardless of what theme markup
       surrounds it — a standard "print only this element" pattern that
       doesn't need to know the theme's specific class names. */
    body *{ visibility:hidden; }
    #printArea, #printArea *{ visibility:visible; }
    #app{display:none;}
    #printArea{
      position:absolute;
      top:0;
      left:0;
      margin:0;
    }
    /* Horizontal margin is intentionally generous (0.35in, vs 0.2in top/
       bottom). An earlier version fit the 2 columns exactly flush against
       the printable width with no slack, which was fine in theory but
       real printers/browsers round margins and box widths slightly
       differently — enough to trim the right-hand label's border. This
       leaves real breathing room instead of a knife-edge fit. */
    @page{ size: letter; margin: 0.2in 0.35in; }
    .sheet{
      display:grid;
      grid-template-columns: repeat(2, 3.7in);
      grid-auto-rows: minmax(2in, auto);
      gap:0.15in 0.2in;
      justify-content:center;
      align-content:start;
      page-break-after:always;
    }
    .sheet:last-child{page-break-after:auto;}
    /* A label that grows past its 2in target (very long institution names,
       even after shrinking) must never be split across a page boundary —
       that's what was pushing "Hub: xxx" onto page 2 by itself while the
       rest of the label stayed on page 1. This keeps each label intact as
       a single unit; if it doesn't fit in the remaining space on a page,
       the whole label moves to the next page rather than tearing. */
    .label--print{
      break-inside:avoid;
      page-break-inside:avoid;
    }
  }
