/* ------------------------------------------------------------------ *
 * Shift Runner house style.
 *
 * Theme red #DF1A25, mark red #E71D21, hover red #C10007, secondary teal
 * (#16A6A1 / #0F7A77). Neutrals are true greys, not the blue-slate this
 * used to run on.
 *
 * The colour jobs are deliberately split so nothing has to mean two
 * things at once:
 *   accent  = brand red. Brand chrome and the primary action, nothing else.
 *   danger  = red as well, but only where something gets destroyed.
 *   due     = amber. Overdue and needs-attention — hi-vis, and it can't be
 *             confused with the brand red sitting next to it.
 *   good    = teal. Done, synced, complete.
 * ------------------------------------------------------------------ */
:root{
    --bg:#F1F1F2; --surface:#FFFFFF; --surface-2:#F7F7F8; --surface-3:#EAEAEC;
    --ink:#171717; --ink-2:#525252; --ink-3:#8A8A8E;
    --line:#E2E2E4; --line-2:#CDCDD1;
    --accent:#C10007; --accent-fill:#DF1A25; --accent-soft:#FDECED;
    --on-accent:#FFFFFF;
    --mark-tile:#16181A; --mark-wedge:#FFFFFF; --mark-red:#E71D21;
    --danger:#C10007; --danger-soft:#FDECED;
    --due:#8A5A04; --due-fill:#F2A81C; --due-soft:#FDF1D8;
    --good:#0F7A77; --good-fill:#16A6A1; --good-soft:#E2F3F2;
    --shadow:0 1px 2px rgba(23,23,23,.05), 0 4px 14px rgba(23,23,23,.06);
    /* Their site runs Milliard, a geometric sans that isn't licensed to us.
       Futura is the closest thing already on every Mac and iPhone; Android
       falls through to its own system sans. */
    --font-display:"Futura","Avenir Next","Century Gothic",system-ui,sans-serif;
    --font-body:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",system-ui,sans-serif;
    --font-mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
  }
  @media (prefers-color-scheme:dark){
    :root:not([data-theme="light"]){
      --bg:#101113; --surface:#191A1D; --surface-2:#1F2124; --surface-3:#2A2C30;
      --ink:#F4F4F5; --ink-2:#B4B5BA; --ink-3:#85868B;
      --line:#2A2C30; --line-2:#3A3D42;
      --accent:#FF6B6B; --accent-fill:#E71D21; --accent-soft:#2E1416;
      --on-accent:#FFFFFF;
      --mark-tile:#F4F4F5; --mark-wedge:#16181A; --mark-red:#E71D21;
      --danger:#FF6B6B; --danger-soft:#2E1416;
      --due:#F2A81C; --due-fill:#F2A81C; --due-soft:#2E2513;
      --good:#2DBFB9; --good-fill:#16A6A1; --good-soft:#0F2A2A;
      --shadow:0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(0,0,0,.28);
    }
  }
  :root[data-theme="dark"]{
    --bg:#101113; --surface:#191A1D; --surface-2:#1F2124; --surface-3:#2A2C30;
    --ink:#F4F4F5; --ink-2:#B4B5BA; --ink-3:#85868B;
    --line:#2A2C30; --line-2:#3A3D42;
    --accent:#FF6B6B; --accent-fill:#E71D21; --accent-soft:#2E1416;
    --on-accent:#FFFFFF;
    --mark-tile:#F4F4F5; --mark-wedge:#16181A; --mark-red:#E71D21;
    --danger:#FF6B6B; --danger-soft:#2E1416;
    --due:#F2A81C; --due-fill:#F2A81C; --due-soft:#2E2513;
    --good:#2DBFB9; --good-fill:#16A6A1; --good-soft:#0F2A2A;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(0,0,0,.28);
  }

  *{box-sizing:border-box;}

  /* An author rule that sets `display` beats the browser's own [hidden] rule
     — they are not in the same cascade layer, and the browser's loses. So
     `.tbtn.icon{display:inline-flex}` quietly un-hid the lock button, which
     is native-only: on the web it sat in the toolbar as a blank tab between
     Reminders and Foreman report. This is the rule that makes `hidden`
     actually mean hidden, everywhere, for good. */
  [hidden]{display:none !important;}

  /* ---- settings ---- *
     A sheet rather than a screen: three preferences are not a destination,
     and coming back from a screen would lose where somebody was. */
  .sheetwrap{position:fixed;inset:0;z-index:60;display:flex;align-items:flex-end;justify-content:center;}
  .sheetback{position:absolute;inset:0;background:rgba(0,0,0,.45);}
  .sheet{position:relative;width:100%;max-width:520px;background:var(--surface);
    border:1px solid var(--line-2);border-bottom:0;border-radius:14px 14px 0 0;
    padding:14px 16px calc(16px + var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)));
    box-shadow:0 -8px 40px rgba(0,0,0,.35);}
  @media (min-width:560px){
    .sheetwrap{align-items:center;}
    .sheet{border-bottom:1px solid var(--line-2);border-radius:14px;}
  }
  .sheethead{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
  .sheethead h2{flex:1;}
  /* The menu is a list of destinations, so each one is a full-width row with
     a thumb-sized target rather than a pill in a wrapped row. */
  .menulist{display:flex;flex-direction:column;gap:10px;}
  /* Sized for a gloved thumb, like the button that opens it — about 56px a
     row rather than 40. Seven of them still fit a phone without scrolling. */
  .menulist .tbtn{width:100%;text-align:left;
    padding:calc(18px * var(--fs)) calc(18px * var(--fs));
    font-size:calc(16px * var(--fs));border-radius:10px;}
  .menulist .tbtn.icon{justify-content:flex-start;}
  .sheethead h2{margin:0;font-family:var(--font-display);font-size:calc(17px * var(--fs));}
  .setrow{display:flex;align-items:center;justify-content:space-between;gap:12px;
    padding:11px 0;border-top:1px solid var(--line);}
  .setrow:first-child{border-top:0;}
  .setlabel{font-size:calc(14px * var(--fs));font-weight:600;color:var(--ink);}
  .setseg{flex-shrink:0;}
  .sheetfoot{margin:12px 0 0;font-size:calc(11.5px * var(--fs));color:var(--ink-3);text-align:center;}

  /* ---- the tidy-up suggestion ---- */
  .assistbtn{margin-top:6px;}
  .assistbox{margin-top:8px;border:1px solid var(--line-2);border-left:3px solid var(--good-fill,var(--accent-fill));
    border-radius:8px;background:var(--surface-2);padding:10px 12px;}
  .assistlabel{margin:0 0 6px;font-size:calc(11px * var(--fs));font-weight:600;
    letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3);}
  .assisttext{font-size:calc(14px * var(--fs));line-height:1.5;color:var(--ink);
    white-space:pre-wrap;margin-bottom:10px;}

  /* ------------------------------------------------------------------ *
   * Text size.
   *
   * Set once on <html> and everything follows: every px font-size in this
   * file is calc(Npx * var(--fs)), and the root size is scaled too so the
   * few rem-based sizes written inline in JS come with it.
   *
   * Only the TEXT grows. Padding and gaps stay put, so a bigger setting
   * fills the boxes rather than pushing the layout about — buttons and rows
   * grow with their content because they are sized by it.
   * ------------------------------------------------------------------ */
  html{--fs:1;font-size:calc(16px * var(--fs));}
  html[data-text="l"]{--fs:1.15;}
  html[data-text="xl"]{--fs:1.32;}
  body{
    margin:0;background:var(--bg);color:var(--ink);
    font-family:var(--font-body);font-size:calc(16px * var(--fs));line-height:1.45;
    -webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;
  }
  .wrap{max-width:640px;margin:0 auto;padding:0 14px 80px;}

  /* masthead */
  .mast{background:var(--surface);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:50;}
  .mast-in{max-width:640px;margin:0 auto;padding:11px 14px 10px;display:flex;flex-direction:column;gap:9px;}
  .mast-top{display:flex;align-items:center;gap:12px;}
  .brand{flex:1;min-width:0;}
  /* The mark takes width off the masthead, so the wordmark has to give a
     little or it wraps to two lines on a 375px phone. */
  .brand h1{
    font-family:var(--font-display);font-weight:700;font-size:calc(20px * var(--fs));line-height:1.08;
    letter-spacing:.01em;text-transform:uppercase;margin:0;
  }
  @media (max-width:359px){ .brand h1{font-size:calc(18px * var(--fs));} }
  /* Scoped to .loc on purpose: this used to be a bare `.brand span` and was
     silently forcing display:block on the sync pill nested inside .who. */
  .brand > span.loc{
    font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.1em;text-transform:uppercase;
    color:var(--ink-3);display:block;margin-top:4px;
  }
  .datebox{text-align:right;flex-shrink:0;}
  .datebox .dow{font-family:var(--font-display);text-transform:uppercase;font-size:calc(19px * var(--fs));font-weight:700;line-height:1;letter-spacing:.03em;}
  .datebox .dnum{font-family:var(--font-mono);font-size:calc(10.5px * var(--fs));color:var(--ink-3);display:block;margin-top:3px;font-variant-numeric:tabular-nums;}
  .meter{display:flex;align-items:center;gap:10px;}
  .meter-track{flex:1;height:7px;border-radius:99px;background:var(--surface-3);overflow:hidden;}
  .meter-fill{height:100%;width:0;border-radius:99px;background:var(--accent-fill);transition:width .3s ease;}
  .meter-fill.done{background:var(--good-fill);}
  .meter-num{font-family:var(--font-mono);font-size:calc(11.5px * var(--fs));font-variant-numeric:tabular-nums;color:var(--ink-2);flex-shrink:0;}
  .toolrow{display:flex;gap:6px;flex-wrap:wrap;}
  /* Menu goes to the right-hand end. Top-left is the hardest corner to reach
     with the hand you are already holding the phone in, and this is the one
     button on the screen. margin-left:auto rather than justify-content, so
     the Management header can keep "← My checklist" on the left and still
     push Menu across. */
  /* Twice the size of an ordinary button. It is the only thing in the header
     now, it is pressed with a glove on, and a 30px target at the top of a
     phone is a fiddle — this is about 56px tall. Scales with the text-size
     setting like everything else. */
  #menubtn, #menubtn2{
    margin-left:auto;
    padding:calc(14px * var(--fs)) calc(20px * var(--fs));
    font-size:calc(15px * var(--fs));
    gap:9px;
    border-radius:10px;
  }
  #menubtn svg, #menubtn2 svg{width:calc(19px * var(--fs));height:calc(19px * var(--fs));}
  .tbtn{
    font-family:var(--font-body);font-size:calc(12px * var(--fs));font-weight:600;
    padding:7px 11px;border-radius:8px;border:1px solid var(--line-2);
    background:var(--surface-2);color:var(--ink-2);cursor:pointer;line-height:1;
    transition:background .15s,color .15s,border-color .15s;
  }
  /* "Add to contacts" is a link now, not a button — an anchor is inline and
     underlined by default, which a .tbtn must not be. */
  a.tbtn{display:inline-block;text-decoration:none;text-align:center;}
  .tbtn:hover{background:var(--surface-3);color:var(--ink);}
  .tbtn:focus-visible{outline:3px solid var(--accent-fill);outline-offset:2px;}

  /* section heads */
  .shead{
    display:flex;align-items:baseline;gap:9px;
    margin:22px 0 8px;padding:0 2px;
  }
  .shead h2{
    font-family:var(--font-display);text-transform:uppercase;letter-spacing:.05em;
    font-size:calc(16px * var(--fs));font-weight:700;margin:0;line-height:1;
  }
  .shead .cnt{font-family:var(--font-mono);font-size:calc(11px * var(--fs));color:var(--ink-3);font-variant-numeric:tabular-nums;margin-left:auto;}

  .card{background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);overflow:hidden;}
  .card + .card{margin-top:10px;}

  /* scope questions */
  .q{display:flex;align-items:center;gap:12px;padding:12px 14px;}
  .q + .q{border-top:1px solid var(--line);}
  .q .qt{flex:1;font-size:calc(15px * var(--fs));line-height:1.3;}
  .seg{display:flex;flex-shrink:0;border:1px solid var(--line-2);border-radius:8px;overflow:hidden;}
  .seg button{
    font-family:var(--font-body);font-size:calc(13px * var(--fs));font-weight:600;
    padding:8px 15px;border:0;background:var(--surface-2);color:var(--ink-3);
    cursor:pointer;line-height:1.1;min-width:52px;
  }
  .seg button + button{border-left:1px solid var(--line-2);}
  .seg button:focus-visible{outline:3px solid var(--accent-fill);outline-offset:-3px;}
  /* Keyed on aria-pressed alone, NOT on the value. These controls carry
     "yes"/"no" on the checklist, "Y"/"N" on the report and "day"/"night" for
     the shift; when the rule named the values, the report's buttons set their
     answer and then looked completely dead. */
  .seg button[aria-pressed="true"]{background:var(--accent-fill);color:var(--on-accent);}
  /* A chosen No used to be surface-3 on surface-2 — #EAEAEC against #F7F7F8,
     about 4% apart, so the only real signal was the text going from grey to
     black. Now "chosen" always means FILLED with inverted text, and the
     colour only says WHICH answer: brand red for yes, solid ink for no.
     ink-2 over surface flips correctly on its own in dark mode (a light
     chip with dark text), so this is one rule, not two. */
  .seg button[aria-pressed="true"][data-v="no"],
  .seg button[aria-pressed="true"][data-v="N"]{background:var(--ink-2);color:var(--surface);}

  /* The shift sets the clock every other time on the list is measured
     against, so it leads the scope card and gets its own weight. */
  .q.shiftq{background:var(--surface-2);}
  .q.shiftq .qt{font-weight:600;}
  .shiftnote{
    margin:0;padding:9px 14px 11px;background:var(--surface-2);
    border-bottom:1px solid var(--line);
    font-size:calc(12.5px * var(--fs));line-height:1.4;color:var(--ink-2);
  }
  .shiftnote b{color:var(--ink);}

  /* A task the app ticks off itself: the box still reads as a checkbox so the
     row scans with the rest, but it can't be tapped. */
  .item.locked{cursor:default;}
  .item.locked input{pointer-events:none;}
  .item.locked .box{opacity:.55;}
  .item.locked input:checked ~ .box{opacity:1;}

  .chipq{padding:12px 14px;border-top:1px solid var(--line);}
  .chipq .qt{font-size:calc(15px * var(--fs));display:flex;align-items:baseline;gap:10px;margin-bottom:9px;}
  /* Sits with the label rather than under the chips: it acts on the whole
     list, and down there it reads as one more chip. */
  .chipclear{
    margin-left:auto;flex:none;background:none;border:0;padding:2px 0;
    color:var(--ink-3);font-size:calc(12.5px * var(--fs));text-decoration:underline;cursor:pointer;
  }
  .chipclear:hover{color:var(--danger);}
  .legend.carried{margin-top:8px;}
  .chips{display:flex;flex-wrap:wrap;gap:6px;}
  .chip{
    font-family:var(--font-body);font-size:calc(13px * var(--fs));font-weight:500;
    padding:7px 12px;border-radius:99px;border:1px solid var(--line-2);
    background:var(--surface-2);color:var(--ink-2);cursor:pointer;line-height:1.1;
  }
  .chip:focus-visible{outline:3px solid var(--accent-fill);outline-offset:2px;}
  .chip[aria-pressed="true"]{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--on-accent);font-weight:600;}
  .chip.wear::before{
    content:"";display:inline-block;width:6px;height:6px;border-radius:99px;
    background:var(--due-fill);margin-right:6px;vertical-align:1px;
  }
  .chip.wear[aria-pressed="true"]::before{background:var(--on-accent);}
  .legend{
    /* align-items:flex-start, not center: a legend that wraps to three lines
       used to hang its dot in the middle of the paragraph. */
    display:flex;align-items:flex-start;gap:7px;margin:10px 0 0;
    font-size:calc(12px * var(--fs));color:var(--ink-3);line-height:1.35;
  }
  /* margin-top pulls the dot onto the first line's optical centre now that
     the row aligns to the top rather than the middle. */
  .legend i{width:6px;height:6px;border-radius:99px;background:var(--due-fill);flex-shrink:0;margin-top:.42em;}

  /* scope summary bar */
  .scopebar{
    display:flex;align-items:center;gap:10px;width:100%;
    padding:12px 14px;background:none;border:0;cursor:pointer;
    font-family:var(--font-body);text-align:left;color:inherit;
  }
  .scopebar:hover{background:var(--surface-2);}
  .scopebar .sum{flex:1;min-width:0;font-size:calc(14px * var(--fs));color:var(--ink-2);line-height:1.35;}
  .scopebar .sum b{color:var(--ink);font-weight:600;}
  .scopebar .edit{
    font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.08em;text-transform:uppercase;
    color:var(--accent);flex-shrink:0;
  }
  .scopebody{display:none;}
  .card.scopeopen .scopebody{display:block;border-top:1px solid var(--line);}
  .card.scopeopen .scopebar{display:none;}

  /* An instruction, not an alarm — a red wash here read as "something is
     wrong". Brand red stays, but as a rule down the side. */
  .prompt{
    padding:13px 14px;background:var(--surface-2);
    border-left:3px solid var(--accent-fill);
    font-size:calc(13.5px * var(--fs));color:var(--ink-2);line-height:1.4;
  }
  .prompt b{color:var(--ink);}

  /* task items */
  .item{
    display:flex;gap:11px;align-items:center;
    padding:12px 14px 12px 12px;border-left:4px solid transparent;
    cursor:pointer;-webkit-tap-highlight-color:transparent;
  }
  .item + .item{border-top:1px solid var(--line);}
  .item:hover{background:var(--surface-2);}
  .item.duetoday{border-left-color:var(--due-fill);}
  .item input{position:absolute;opacity:0;width:0;height:0;}
  .box{
    flex-shrink:0;width:24px;height:24px;
    border:2px solid var(--line-2);border-radius:6px;background:var(--surface);
    display:grid;place-items:center;transition:background .15s,border-color .15s;
  }
  .box svg{width:14px;height:14px;stroke:#fff;stroke-width:3.2;fill:none;
    stroke-linecap:round;stroke-linejoin:round;opacity:0;transform:scale(.5);
    transition:opacity .15s,transform .15s;}
  .item input:checked ~ .box{background:var(--good-fill);border-color:var(--good-fill);}
  .item input:checked ~ .box svg{opacity:1;transform:scale(1);}
  .item input:focus-visible ~ .box{outline:3px solid var(--accent-fill);outline-offset:2px;}
  .txt{flex:1;min-width:0;font-size:calc(15px * var(--fs));line-height:1.35;}
  .item input:checked ~ .txt{color:var(--ink-3);}
  /* No strikethrough on a finished task. The ticked box already says it, and
     a list of struck-out lines is hard to read at a glance on a phone. The
     text only fades. */
  .item input:checked ~ .txt .lbl{color:var(--ink-3);}

  /* ? hint */
  .help{
    display:inline-flex;align-items:center;justify-content:center;
    width:18px;height:18px;padding:0;margin-left:7px;flex-shrink:0;
    border:1px solid var(--line-2);border-radius:99px;background:var(--surface-2);
    color:var(--ink-3);font-family:var(--font-mono);font-size:calc(10px * var(--fs));font-weight:700;
    line-height:1;cursor:pointer;vertical-align:-1px;
  }
  .help:hover,.help[aria-expanded="true"]{
    background:var(--accent-soft);border-color:var(--accent);color:var(--accent);
  }
  .help:focus-visible{outline:3px solid var(--accent-fill);outline-offset:2px;}
  .hint{
    display:none;margin-top:8px;padding:10px 12px;
    background:var(--surface-2);border-left:3px solid var(--accent-fill);
    border-radius:0 8px 8px 0;
    font-size:calc(13px * var(--fs));line-height:1.5;color:var(--ink-2);
    white-space:pre-line;
  }
  .item.helpopen .hint{display:block;}
  /* an open hint makes the row tall — keep the box beside the first line */
  .item.helpopen{align-items:flex-start;}
  .item.helpopen .box{margin-top:1px;}
  /* The same note on a start-of-day question. That row is a .q, not a .item,
     so it needs its own rule — without it the hint is written into the page
     and never shown. Yes/No moves to the top of the row while it is open so
     the buttons do not float in the middle of the note. */
  .q.helpopen .hint{display:block;}
  .q.helpopen{align-items:flex-start;}
  .q.helpopen .seg{margin-top:1px;}
  /* On a mouse, hovering the ? opens the hint and it stays open until the
     pointer leaves the ROW — not the instant it slips off the little button,
     which made it impossible to read. The class is put on by app.js; the old
     rule was `.help:hover ~ .hint`, which closed far too eagerly. */
  @media (hover:hover){
    .item.hoveropen .hint,
    .arow.hoveropen .hint,
    .q.hoveropen .hint{display:block;}
  }
  .tag{
    font-family:var(--font-mono);font-size:calc(9px * var(--fs));letter-spacing:.09em;text-transform:uppercase;
    padding:3px 6px;border-radius:4px;margin-left:7px;white-space:nowrap;vertical-align:2px;
    background:var(--surface-3);color:var(--ink-3);
  }
  .tag.due{background:var(--due-soft);color:var(--due);}
  .tag.ok{background:var(--good-soft);color:var(--good);}
  .item input:checked ~ .txt .tag{opacity:.5;}

  /* wear watch rows */
  .wrow{display:flex;align-items:stretch;}
  .wrow + .wrow{border-top:1px solid var(--line);}
  .wrow .item{flex:1;min-width:0;border-top:0;}
  .wrow .item + .item{border-top:0;}
  .watchitem .wmain{display:block;font-size:calc(15px * var(--fs));line-height:1.25;font-weight:600;}
  .watchitem .wmeta{
    display:block;font-family:var(--font-mono);font-size:calc(10.5px * var(--fs));
    letter-spacing:.03em;color:var(--ink-3);margin-top:3px;
  }
  .wrow.wdone .wmain{color:var(--ink-3);}
  .wrow .item input:checked ~ .txt{text-decoration:none;color:inherit;}
  .repl{
    flex-shrink:0;border:0;border-left:1px solid var(--line);
    background:var(--surface-2);color:var(--ink-3);
    font-family:var(--font-body);font-size:calc(10.5px * var(--fs));font-weight:600;line-height:1.2;
    padding:0 11px;cursor:pointer;text-align:center;
  }
  .repl:hover{background:var(--good-soft);color:var(--good);}
  .repl:focus-visible{outline:3px solid var(--accent-fill);outline-offset:-3px;}

  /* flag-a-unit form */
  .addwrap{border-top:1px solid var(--line);}
  .addbtn{
    display:block;width:100%;padding:13px 14px;border:0;background:none;
    font-family:var(--font-body);font-size:calc(14px * var(--fs));font-weight:600;color:var(--accent);
    cursor:pointer;text-align:left;
  }
  .addbtn:hover{background:var(--surface-2);}
  .addbtn:focus-visible{outline:3px solid var(--accent-fill);outline-offset:-3px;}
  .addwrap.open{background:var(--surface-2);padding:12px 14px 14px;}
  .addhint{margin:0 0 10px;font-size:calc(12.5px * var(--fs));color:var(--ink-3);line-height:1.4;}
  .addgrid{display:flex;gap:8px;}
  .addgrid input{
    flex:1;min-width:0;font-family:var(--font-body);font-size:calc(15px * var(--fs));
    color:var(--ink);background:var(--surface);
    border:1px solid var(--line-2);border-radius:8px;padding:9px 10px;
  }
  .addgrid input::placeholder{color:var(--ink-3);}
  .addgrid input:focus{outline:2px solid var(--accent-fill);border-color:var(--accent-fill);}
  .detect{
    margin:8px 0 0;font-family:var(--font-mono);font-size:calc(11.5px * var(--fs));
    letter-spacing:.04em;color:var(--ink-3);line-height:1.35;min-height:16px;
  }
  .detect.found{color:var(--good);font-weight:600;letter-spacing:.06em;text-transform:uppercase;}
  .detect.unknown{color:var(--due);}
  .addbtns{display:flex;gap:8px;margin-top:10px;}
  .addbtns .tbtn{flex:1;padding:11px;font-size:calc(14px * var(--fs));}
  .addbtns .go{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--on-accent);}
  .addbtns .go:hover{background:var(--accent-fill);color:var(--on-accent);filter:brightness(1.06);}

  .empty{padding:16px 14px;font-size:calc(14px * var(--fs));color:var(--ink-3);line-height:1.4;}

  .foot{margin-top:24px;padding:14px 4px 0;border-top:1px solid var(--line);font-size:calc(12px * var(--fs));color:var(--ink-3);line-height:1.5;}
  .toast{
    position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(20px);
    background:var(--ink);color:var(--bg);font-size:calc(13.5px * var(--fs));font-weight:600;
    padding:10px 16px;border-radius:9px;opacity:0;pointer-events:none;
    transition:opacity .2s,transform .2s;z-index:99;box-shadow:0 6px 24px rgba(0,0,0,.3);
  }
  .toast.show{opacity:1;transform:translateX(-50%) translateY(0);}
  .toast .undo{
    margin-left:14px;border:0;background:none;padding:0;
    font-family:var(--font-body);font-size:calc(13.5px * var(--fs));font-weight:700;
    color:var(--accent-fill);cursor:pointer;text-decoration:underline;
  }
  .toast .undo:focus-visible{outline:2px solid var(--accent-fill);outline-offset:3px;}
  .tbtn.icon{display:inline-flex;align-items:center;gap:5px;}
  .tbtn.icon svg{width:13px;height:13px;flex-shrink:0;}

  @media (prefers-reduced-motion:reduce){*{transition:none !important;}}
  @media print{.mast{position:static;}.toolrow,.toast,.scopebar .edit{display:none;}body{background:#fff;}.card{box-shadow:none;}}

  /* ---- explicit theme choice ----
     Last in the sheet on purpose: same specificity as the host's [data-theme]
     stamp, so source order lets the supervisor's pick win either way. */
  :root[data-app-theme="light"]{
    --bg:#F1F1F2; --surface:#FFFFFF; --surface-2:#F7F7F8; --surface-3:#EAEAEC;
    --ink:#171717; --ink-2:#525252; --ink-3:#8A8A8E;
    --line:#E2E2E4; --line-2:#CDCDD1;
    --accent:#C10007; --accent-fill:#DF1A25; --accent-soft:#FDECED;
    --on-accent:#FFFFFF;
    --mark-tile:#16181A; --mark-wedge:#FFFFFF; --mark-red:#E71D21;
    --danger:#C10007; --danger-soft:#FDECED;
    --due:#8A5A04; --due-fill:#F2A81C; --due-soft:#FDF1D8;
    --good:#0F7A77; --good-fill:#16A6A1; --good-soft:#E2F3F2;
    --shadow:0 1px 2px rgba(23,23,23,.05), 0 4px 14px rgba(23,23,23,.06);
  }
  :root[data-app-theme="dark"]{
    --bg:#101113; --surface:#191A1D; --surface-2:#1F2124; --surface-3:#2A2C30;
    --ink:#F4F4F5; --ink-2:#B4B5BA; --ink-3:#85868B;
    --line:#2A2C30; --line-2:#3A3D42;
    --accent:#FF6B6B; --accent-fill:#E71D21; --accent-soft:#2E1416;
    --on-accent:#FFFFFF;
    --mark-tile:#F4F4F5; --mark-wedge:#16181A; --mark-red:#E71D21;
    --danger:#FF6B6B; --danger-soft:#2E1416;
    --due:#F2A81C; --due-fill:#F2A81C; --due-soft:#2E2513;
    --good:#2DBFB9; --good-fill:#16A6A1; --good-soft:#0F2A2A;
    --shadow:0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(0,0,0,.28);
  }

/* ================================================================== *
 * Screens — auth, checklist, admin
 * ================================================================== */
.screen{display:none;}
.screen.active{display:block;}

/* ---- sign in ---- */
.authwrap{
  max-width:400px;margin:0 auto;padding:36px 18px 60px;
  min-height:100vh;display:flex;flex-direction:column;justify-content:center;
}
/* brand mark — one <symbol>, sized by where it lands */
.mark{width:36px;height:36px;flex-shrink:0;display:block;}
.mark.big{width:64px;height:64px;margin:0 auto 14px;}
@media (max-width:359px){ .mark{width:31px;height:31px;} }

.authmark{text-align:center;margin-bottom:26px;}
.authmark h1{
  font-family:var(--font-display);font-weight:700;font-size:calc(34px * var(--fs));line-height:1;
  letter-spacing:.02em;text-transform:uppercase;margin:0;
}
.authmark p{
  font-family:var(--font-mono);font-size:calc(10.5px * var(--fs));letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);margin:8px 0 0;
}
.authcard{
  background:var(--surface);border:1px solid var(--line);border-radius:14px;
  box-shadow:var(--shadow);padding:20px 18px;
}
.authcard h2{
  font-family:var(--font-display);text-transform:uppercase;letter-spacing:.04em;
  font-size:calc(19px * var(--fs));font-weight:700;margin:0 0 4px;
}
.authcard .sub{font-size:calc(13.5px * var(--fs));color:var(--ink-3);margin:0 0 18px;line-height:1.4;}
.field{margin-bottom:14px;}
.field label{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:6px;
}
.field input{
  width:100%;font-family:var(--font-body);font-size:calc(16px * var(--fs));
  color:var(--ink);background:var(--surface-2);
  border:1px solid var(--line-2);border-radius:9px;padding:12px 12px;
}
.field input:focus{outline:2px solid var(--accent-fill);border-color:var(--accent-fill);}
.field input.pin{
  font-family:var(--font-mono);font-size:calc(24px * var(--fs));letter-spacing:.6em;
  text-align:center;padding:12px 0 12px 12px;
}
.bigbtn{
  width:100%;padding:14px;border-radius:9px;border:0;
  background:var(--accent-fill);color:var(--on-accent);
  font-family:var(--font-body);font-size:calc(16px * var(--fs));font-weight:700;cursor:pointer;
}
.bigbtn:hover{filter:brightness(1.06);}
.bigbtn:disabled{opacity:.5;cursor:default;filter:none;}
.bigbtn:focus-visible{outline:3px solid var(--accent);outline-offset:2px;}
/* A way out, not a warning — in red this read as "something has gone wrong"
   before you had even typed anything. */
.linkbtn{
  display:block;width:100%;margin-top:14px;padding:10px;
  background:none;border:0;color:var(--ink-2);cursor:pointer;
  font-family:var(--font-body);font-size:calc(13.5px * var(--fs));font-weight:600;
  text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:var(--line-2);
}
.linkbtn:hover{color:var(--ink);text-decoration-color:var(--ink-3);}
.autherr{
  margin:0 0 14px;padding:11px 12px;border-radius:9px;
  background:var(--due-soft);border-left:3px solid var(--due-fill);
  color:var(--due);font-size:calc(13.5px * var(--fs));line-height:1.4;
}
.autherr:empty{display:none;}
.authnote{
  margin:18px 4px 0;font-size:calc(12px * var(--fs));color:var(--ink-3);line-height:1.5;text-align:center;
}

/* ---- sync pill in the masthead ---- */
.who{display:flex;align-items:center;gap:8px;font-size:calc(12px * var(--fs));color:var(--ink-3);}
.who b{color:var(--ink-2);font-weight:600;}
.sync{
  display:inline-flex;align-items:center;gap:5px;
  font-family:var(--font-mono);font-size:calc(9.5px * var(--fs));letter-spacing:.07em;
  text-transform:uppercase;padding:3px 7px;border-radius:99px;
  background:var(--surface-3);color:var(--ink-3);
}
.sync i{width:6px;height:6px;border-radius:99px;background:var(--ink-3);flex-shrink:0;}
.sync.ok{background:var(--good-soft);color:var(--good);}
.sync.ok i{background:var(--good-fill);}
.sync.pending{background:var(--accent-soft);color:var(--accent);}
.sync.pending i{background:var(--accent-fill);}
.sync.off{background:var(--due-soft);color:var(--due);}
.sync.off i{background:var(--due-fill);}

/* ---- admin ---- */
.tabs{display:flex;gap:6px;margin:16px 0 2px;}
.tab{
  font-family:var(--font-body);font-size:calc(13px * var(--fs));font-weight:600;
  padding:9px 13px;border-radius:9px 9px 0 0;border:1px solid var(--line);
  border-bottom:0;background:var(--surface-2);color:var(--ink-3);cursor:pointer;
}
.tab[aria-selected="true"]{background:var(--surface);color:var(--ink);}
.gridwrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table.grid{border-collapse:collapse;width:100%;font-size:calc(13px * var(--fs));}
table.grid th,table.grid td{
  padding:9px 10px;text-align:left;border-bottom:1px solid var(--line);white-space:nowrap;
}
table.grid thead th{
  font-family:var(--font-mono);font-size:calc(9.5px * var(--fs));letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-3);font-weight:600;background:var(--surface-2);
  position:sticky;top:0;z-index:1;
}
table.grid td.name{font-weight:600;position:sticky;left:0;background:var(--surface);}
table.grid tbody tr:hover td{background:var(--surface-2);}
table.grid tbody tr:hover td.name{background:var(--surface-2);}
.cell{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;border-radius:6px;font-size:calc(12px * var(--fs));font-weight:700;
}
.cell.done{background:var(--good-soft);color:var(--good);}
.cell.missed{background:var(--due-soft);color:var(--due);}
.cell.pending{background:var(--surface-3);color:var(--ink-3);}
.cell.na{background:transparent;color:var(--line-2);}
.score{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
.legend2{
  display:flex;flex-wrap:wrap;gap:14px;margin:12px 2px 0;
  font-size:calc(11.5px * var(--fs));color:var(--ink-3);
}
.legend2 span{display:inline-flex;align-items:center;gap:6px;}
/* On a phone this select is wider than the space left beside the title and
   was printing straight over "Admin". Let it shrink instead. */
.weekpick{
  font-family:var(--font-mono);font-size:calc(12px * var(--fs));color:var(--ink);
  background:var(--surface);border:1px solid var(--line-2);
  border-radius:8px;padding:8px 10px;
  width:100%;
}
/* a select will not shrink below its longest option on its own — the cap
   on the wrapper is what actually stops it eating the title */
#screen-admin .datebox{flex-shrink:1;min-width:0;max-width:52%;}
/* Which site the tab below is about. Only drawn when there's more than one,
   so a single-site install never sees it. */
.sitebar{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  padding:9px 12px;margin:14px 0 4px;box-shadow:var(--shadow);
}
.sitebar label{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);
}
.sitebar .weekpick{flex:1;min-width:0;max-width:320px;}
.sitenote{font-size:calc(12px * var(--fs));color:var(--ink-3);}
.copyrow{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-top:10px;font-size:calc(13px * var(--fs));color:var(--ink-2);
}
.copyrow .weekpick{flex:1;min-width:150px;}
.sitesel{width:100%;max-width:190px;font-size:calc(11.5px * var(--fs));padding:5px 7px;}

.loading{padding:26px 14px;text-align:center;color:var(--ink-3);font-size:calc(14px * var(--fs));}

/* The admin grid is read on a laptop, not in a truck — let it breathe. */
#screen-admin .wrap{max-width:1180px;}
#screen-admin .mast-in{max-width:1180px;}
@media (max-width:700px){
  #screen-admin .wrap,#screen-admin .mast-in{max-width:640px;}
}

/* ---- one-time temporary PIN callout ---- */
.pinout{
  margin-top:14px;padding:14px;border-radius:10px;
  background:var(--accent-soft);border:1px solid var(--accent-fill);
}
.pinlead{margin:0;font-size:calc(13.5px * var(--fs));color:var(--ink-2);line-height:1.4;}
.pinlead b{color:var(--ink);}
.pincode{
  margin:10px 0;font-family:var(--font-mono);font-size:calc(38px * var(--fs));font-weight:700;
  letter-spacing:.22em;text-align:center;color:var(--accent);
  font-variant-numeric:tabular-nums;
}
.pinnote{margin:0;font-size:calc(12px * var(--fs));color:var(--ink-3);line-height:1.45;}
.tbtn.danger:hover{background:var(--danger-soft);border-color:var(--danger);color:var(--danger);}
table.grid td .tbtn{padding:5px 9px;font-size:calc(11.5px * var(--fs));margin-right:4px;}

/* the identity line sits inline: name then sync pill */
.brand .who{margin-top:5px;}
.brand .who .sync span{display:inline;margin:0;}

/* ================================================================== *
 * Master list editor
 * ================================================================== */
.esec .erows{display:flex;flex-direction:column;}
.erow{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  padding:11px 14px;border-top:1px solid var(--line);
}
.erow:first-child{border-top:0;}
.erow:hover{background:var(--surface-2);}
.ermain{display:flex;flex:1;min-width:220px;gap:8px;align-items:center;}
.etext{
  flex:1;min-width:0;font-family:var(--font-body);font-size:calc(15px * var(--fs));
  color:var(--ink);background:var(--surface);
  border:1px solid var(--line-2);border-radius:8px;padding:10px 11px;
}
.etext:focus{outline:2px solid var(--accent-fill);border-color:var(--accent-fill);}
.etext::placeholder{color:var(--ink-3);}
.eday{
  flex-shrink:0;font-family:var(--font-body);font-size:calc(13px * var(--fs));
  color:var(--ink);background:var(--surface);
  border:1px solid var(--line-2);border-radius:8px;padding:10px 8px;max-width:170px;
}
.eday:focus{outline:2px solid var(--accent-fill);border-color:var(--accent-fill);}
.elabel{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:6px;
}
.eractions{display:flex;align-items:center;gap:5px;flex-shrink:0;}
.ebtn{
  /* Square for a single glyph, but it grows for a word: Rename, Archive,
     Delete and Remove all were spilling out of a fixed 32px box. min-width
     keeps the ✕ buttons square, the padding only shows once there is text
     wide enough to need it. */
  min-width:32px;height:32px;flex-shrink:0;padding:0 9px;white-space:nowrap;
  border:1px solid var(--line-2);border-radius:8px;
  background:var(--surface-2);color:var(--ink-3);
  font-family:var(--font-body);font-size:calc(14px * var(--fs));font-weight:600;
  cursor:pointer;display:grid;place-items:center;
}
.ebtn:hover{background:var(--surface-3);color:var(--ink);}
.ebtn.has{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);}
.ebtn.del:hover{background:var(--danger-soft);border-color:var(--danger);color:var(--danger);}
.ebtn:focus-visible{outline:3px solid var(--accent-fill);outline-offset:2px;}
.echk{
  display:inline-flex;align-items:center;gap:6px;flex-shrink:0;
  font-size:calc(12px * var(--fs));color:var(--ink-2);cursor:pointer;white-space:nowrap;
  padding:0 6px 0 2px;
}
.echk input{width:16px;height:16px;accent-color:var(--accent-fill);cursor:pointer;}
.erhint{flex-basis:100%;padding:2px 0 2px 2px;}
.erhint label{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:6px;
}
.erhint textarea{
  width:100%;font-family:var(--font-body);font-size:calc(14px * var(--fs));line-height:1.5;
  color:var(--ink);background:var(--surface);
  border:1px solid var(--line-2);border-left:3px solid var(--accent-fill);
  border-radius:0 8px 8px 0;padding:10px 11px;resize:vertical;
}
.erhint textarea:focus{outline:2px solid var(--accent-fill);}

/* sticky publish bar */
.savebar{
  position:sticky;bottom:0;z-index:20;
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin-top:18px;padding:12px 14px;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 -4px 18px rgba(0,0,0,.10);
}
/* the red button is the call to action; ringing the whole bar in red made
   a routine "ready to send" look like a failure */
.savebar.on{border-color:var(--line-2);}
.savemsg{
  flex:1;min-width:130px;font-size:calc(13.5px * var(--fs));font-weight:600;color:var(--ink-3);
}
.savebar.on .savemsg{color:var(--ink-2);}
.savebar .tbtn{padding:10px 14px;font-size:calc(14px * var(--fs));}
.savebar .tbtn:disabled{opacity:.45;cursor:default;}
.savebar .go{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--on-accent);}
.savebar .go:hover:not(:disabled){filter:brightness(1.06);background:var(--accent-fill);color:var(--on-accent);}
@media (max-width:520px){
  .eday{max-width:none;flex:1;}
  .ermain{flex-basis:100%;}
}

/* ---- reminders ---- */
.tag.clock{
  background:var(--surface-3);color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.tag.due.clock{background:var(--due-soft);color:var(--due);}
.etime{max-width:150px;}

.alertbox{
  display:flex;align-items:flex-start;gap:11px;
  margin-top:14px;padding:12px 13px;border-radius:11px;
  background:var(--due-soft);border:1px solid var(--due-fill);border-left-width:5px;
}
.alertbox.soon{background:var(--accent-soft);border-color:var(--accent-fill);}
.alertbox .abody{flex:1;min-width:0;}
.alertbox .atitle{
  font-family:var(--font-display);text-transform:uppercase;letter-spacing:.04em;
  font-size:calc(15px * var(--fs));font-weight:700;color:var(--due);display:block;line-height:1.1;
}
.alertbox.soon .atitle{color:var(--accent);}
.alertbox .amsg{display:block;margin-top:4px;font-size:calc(13.5px * var(--fs));color:var(--ink-2);line-height:1.4;}
.alertbox .adismiss{
  flex-shrink:0;width:28px;height:28px;padding:0;border:0;border-radius:8px;
  background:transparent;color:var(--ink-3);cursor:pointer;font-size:calc(15px * var(--fs));
}
.alertbox .adismiss:hover{background:var(--surface-3);color:var(--ink);}

.notifynag{
  margin-top:14px;padding:12px 13px;border-radius:11px;
  background:var(--surface);border:1px solid var(--line);
  display:flex;align-items:center;gap:11px;flex-wrap:wrap;
}
.notifynag p{margin:0;flex:1;min-width:180px;font-size:calc(13px * var(--fs));color:var(--ink-2);line-height:1.4;}

.tag.owner{background:var(--accent-soft);color:var(--accent);font-weight:700;}
.lockednote{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);
}

/* one-time recovery codes */
.codegrid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:12px 0;
}
.codegrid span{
  font-family:var(--font-mono);font-size:calc(15px * var(--fs));font-weight:600;letter-spacing:.08em;
  text-align:center;padding:9px 4px;border-radius:7px;
  background:var(--surface);border:1px solid var(--accent-fill);color:var(--ink);
}
@media (max-width:420px){.codegrid{grid-template-columns:1fr;}}

/* ================================================================== *
 * Foreman Report
 * ================================================================== */
.frm{display:flex;flex-direction:column;gap:12px;padding:12px 14px;}
.fld{display:flex;flex-direction:column;gap:6px;}
.fld label{
  font-family:var(--font-mono);font-size:calc(10px * var(--fs));letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);
}
.fld .etext{width:100%;}
/* iOS gives a date box an intrinsic width and ignores width:100% until its
   native appearance is switched off — on an iPhone the Date field ran off
   the right edge of the card. The value is left-aligned to match the boxes
   under it; iOS centres it by default. */
.fld input[type="date"].etext{-webkit-appearance:none;appearance:none;min-width:0;max-width:100%;display:block;}
.fld input[type="date"].etext::-webkit-date-and-time-value{text-align:left;}
.fld select.etext{appearance:none;background-image:none;}
.ynseg{align-self:flex-start;}
.ynseg button{min-width:56px;font-size:calc(15px * var(--fs));padding:10px 16px;}

/* repeating rows */
.rrow{border-top:1px solid var(--line);}
.rrow:first-of-type{border-top:0;}
.rrowhead{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 14px 0;
}
.rrowhead span{
  font-family:var(--font-mono);font-size:calc(11px * var(--fs));font-weight:700;
  color:var(--ink-3);background:var(--surface-3);
  width:22px;height:22px;border-radius:6px;display:grid;place-items:center;
}

/* photos */
.pgrid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
  gap:10px;padding:12px 14px;
}
.pcard{
  margin:0;background:var(--surface-2);border:1px solid var(--line);
  border-radius:10px;overflow:hidden;display:flex;flex-direction:column;
}
.pcard img{width:100%;height:110px;object-fit:cover;display:block;background:var(--surface-3);}
.pnothumb{
  height:110px;display:grid;place-items:center;background:var(--surface-3);
  color:var(--ink-3);font-size:calc(11px * var(--fs));
}
.pcard figcaption{padding:8px;display:flex;flex-direction:column;gap:6px;}
.pcard .etext{font-size:calc(13px * var(--fs));padding:7px 8px;}
/* Three labelled prompts per picture — labelled because "where" and "what"
   are not guessable from a bare box, and the office needs both. */
/* Flagged when a send was stopped because this picture has no description. */
.pcard.needs{outline:2px solid var(--due-fill);outline-offset:1px;}
/* The same marking for a field the report is waiting on, so "still needs X"
   and the thing on screen agree about which one X is. */
.fld.needs, .rrow.needs, .card.needs{outline:2px solid var(--due-fill);outline-offset:1px;border-radius:8px;}
.fld.needs label, .rrow.needs .rrowhead span{color:var(--due);}
.pcard.needs .pfld:nth-child(2) label{color:var(--due);}
.pfld{display:flex;flex-direction:column;gap:3px;}
.pfld label{
  font-family:var(--font-mono);font-size:calc(9.5px * var(--fs));letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3);
}
.pmeta{
  font-family:var(--font-mono);font-size:calc(9.5px * var(--fs));letter-spacing:.03em;
  color:var(--ink-3);line-height:1.3;
}
.pcard .ebtn.del{width:auto;height:26px;font-size:calc(11px * var(--fs));padding:0 8px;}
.photobtn{
  display:block;text-align:center;cursor:pointer;margin:0;
}

/* ---- spreadsheet import ---- */
.dropzone{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  padding:22px 14px;border:2px dashed var(--line-2);border-radius:12px;
  background:var(--surface-2);cursor:pointer;text-align:center;
  transition:border-color .15s, background .15s;
}
.dropzone:hover, .dropzone.over{border-color:var(--accent-fill);background:var(--accent-soft);}
.dropzone b{font-size:calc(14px * var(--fs));color:var(--ink);}
.dropzone span{font-size:calc(12px * var(--fs));color:var(--ink-3);}
/* Typing a contact in by hand. One column on a phone, two once there is room
   — six stacked boxes on a laptop is a form that looks longer than it is. */
.cform{display:grid;grid-template-columns:1fr;gap:10px;}
@media (min-width:560px){ .cform{grid-template-columns:1fr 1fr;} }
.cform label{display:flex;flex-direction:column;gap:4px;}
.cform span{font-size:calc(11px * var(--fs));letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);}
.cform input, .cform select{
  font-family:var(--font-body);font-size:calc(15px * var(--fs));color:var(--ink);
  padding:9px 11px;border:1px solid var(--line-2);border-radius:9px;background:var(--surface);
}
/* Matches the inputs beside it rather than the platform's own control, which
   on a phone is a different height and breaks the row. */
.cform select{appearance:none;-webkit-appearance:none;height:40px;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 16px) 18px,calc(100% - 11px) 18px;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:30px;}
.cform input:focus, .cform select:focus{outline:2px solid var(--accent-fill);outline-offset:1px;border-color:var(--accent-fill);}
/* A description runs the width of the form; a packing slip number does not. */
.cform label.wide{grid-column:1/-1;}
.cform textarea{
  font-family:var(--font-body);font-size:calc(15px * var(--fs));color:var(--ink);
  padding:9px 11px;border:1px solid var(--line-2);border-radius:9px;background:var(--surface);
}
/* Marks the fields the office cannot process the report without.
   A red asterisk, which is what people expect on a form. It carries its own
   title so it is not a bare glyph — hover explains it, a screen reader reads
   it, and no legend is needed at the top of the page. text-decoration is
   reset because a browser underlines <abbr> by default. */
.cform .req, .fld .req, .pfld .req, .shead .req{
  font-style:normal;font-weight:700;color:var(--danger);
  font-size:calc(15px * var(--fs));line-height:1;margin-left:3px;
  text-decoration:none;border-bottom:0;cursor:help;
}

/* ---- site wording suggestions ---- */
.fixrow{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px;}
.fixchip{
  display:inline-flex;align-items:center;gap:5px;
  font-family:var(--font-body);font-size:calc(12px * var(--fs));font-weight:600;
  padding:5px 9px;border-radius:7px;cursor:pointer;
  background:var(--due-soft);border:1px solid var(--due-fill);color:var(--due);
}
/* The wrong word struck through, the site's word after it — so the chip says
   what it will do rather than just offering a word with no context. */
.fixchip s{opacity:.65;font-weight:500;text-decoration:line-through;}
.fixchip:hover{background:var(--due-fill);color:var(--on-accent);}
.fixchip:hover s{opacity:.8;}

/* ---- material receiving ---- */
.mrow{margin-bottom:10px;}
.mrowhead{
  display:flex;align-items:center;gap:10px;
  padding:10px 14px 8px;border-bottom:1px solid var(--line);margin-bottom:12px;
}
.mrowhead b{flex:1;font-size:calc(13px * var(--fs));letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2);}
/* The picture buttons are <label for=input>, so they need to look and size
   like the buttons beside them. */
.tbtn.wide{display:block;width:100%;padding:11px;text-align:center;font-size:calc(14px * var(--fs));cursor:pointer;}
.plist{display:flex;flex-direction:column;gap:6px;margin-bottom:10px;}
.prow{
  display:flex;align-items:center;gap:10px;font-size:calc(12.5px * var(--fs));color:var(--ink-2);
  padding:6px 10px;background:var(--surface-2);border:1px solid var(--line);border-radius:8px;
}
.prow span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.sendwrap{padding:16px 0 40px;}
.findrow{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:9px 0;border-top:1px solid var(--line);
}
.findlabel{flex:1;min-width:180px;font-size:calc(13.5px * var(--fs));color:var(--ink);}
.findjob{max-width:110px;}
.findnote{display:block;font-size:calc(11.5px * var(--fs));color:var(--due);margin-top:2px;}
/* The machine type on an hours row: derived from the unit number, never typed. */
.rowtype{
  display:block;margin-top:5px;
  font-family:var(--font-mono);font-size:calc(10.5px * var(--fs));letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-3);
}

/* Shortcut from a task row to the screen that does it. */
.gobtn{
  font-family:var(--font-body);font-size:calc(11.5px * var(--fs));font-weight:700;
  margin-left:8px;padding:3px 9px;border-radius:99px;
  border:1px solid var(--accent-fill);background:var(--accent-soft);
  color:var(--accent);cursor:pointer;line-height:1.35;white-space:nowrap;
  vertical-align:1px;
}
.gobtn:hover{background:var(--accent-fill);color:var(--on-accent);}
.item.locked .gobtn{pointer-events:auto;}

/* Switching between reports when a supervisor covers more than one scope. */
.rtabs{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0 4px;}
.rtab{
  font-family:var(--font-body);font-size:calc(12.5px * var(--fs));font-weight:600;
  padding:8px 12px;border-radius:99px;border:1px solid var(--line-2);
  background:var(--surface);color:var(--ink-2);cursor:pointer;line-height:1.2;
}
.rtab.on{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--on-accent);}
.rtab.on .tag{background:rgba(255,255,255,.22);color:var(--on-accent);}
.rtab.add{border-style:dashed;color:var(--ink-3);}
.rtab.add:hover{color:var(--ink);border-color:var(--line-2);}

/* ==================================================================== *
 * Tablets (iPad).
 *
 * Everything above this point was written phone-first, and every breakpoint
 * in the sheet is a max-width one — so any screen wider than a phone got the
 * same 640px column. On an iPad in landscape that left roughly half the
 * display empty while a four-field section scrolled for pages, with a date
 * box stretched to 640px to hold ten characters.
 *
 * These are the only min-width rules here. They widen the column and let
 * short form fields sit side by side. Nothing below changes the phone
 * layout, because nothing below applies at phone widths.
 * ==================================================================== */

@media (min-width:768px){
  .wrap,.mast-in{max-width:860px;}

  /* The report and hours forms are schema-driven, so the number of fields in
     a section is not known here. auto-fit lets the browser decide how many
     columns fit: a two-field section stays two, a longer one spreads, and no
     per-section markup is needed. */
  .frm{
    display:grid;
    grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
    gap:12px 16px;
    align-items:start;
  }
  /* Anything you actually write prose into keeps the full width — a
     description box squeezed into a 250px column is worse than no change. */
  .fld:has(textarea){grid-column:1/-1;}
}

@media (min-width:1024px){
  .wrap,.mast-in{max-width:1040px;}

  /* Scope questions two-up. In one column at this width the Yes/No sits a
     hand's width away from the question it answers. */
  /* Must be `.card.scopeopen .scopebody` and not just `.scopebody`: the
     collapse is done with display, and that selector outranks a bare class.
     Staying inside .scopeopen also keeps the collapsed state hidden. */
  .card.scopeopen .scopebody{
    display:grid;
    grid-template-columns:1fr 1fr;
    column-gap:0;
  }
  .scopebody .prompt,
  .scopebody .chipq{grid-column:1/-1;}
  /* The single-column rule was `.q + .q`, which in a grid would skip the
     second column's first row and draw the wrong dividers. */
  .q{border-top:1px solid var(--line);}
  .q + .q{border-top:1px solid var(--line);}
  .scopebody .q:nth-child(odd){border-right:1px solid var(--line);}
}

/* ---- Assigned to you -------------------------------------------------
   One-off tasks from an admin. Built on .q (the scope-question row) because
   it is the same shape: a label on the left, a two-button segment on the
   right. Two buttons, not a checkbox — "read it" and "did it" are separate
   answers and the office needs both. */
.arow{align-items:flex-start;}
.arow .qt{display:block;}
.arow .lbl{display:block;font-size:calc(15px * var(--fs));line-height:1.35;}
.arow .pmeta{display:inline;font-size:calc(11.5px * var(--fs));color:var(--ink-3);}
.arow .seg{flex-shrink:0;margin-top:2px;}
.arow.helpopen .hint{display:block;}
/* Done fades back rather than disappearing — it stays on the list as proof
   it was handled, unlike a daily task which simply clears. */
.arow-done .lbl{color:var(--ink-3);}
.arow-done{background:var(--surface-2);}

/* ==================================================================== *
 * The sign-in page as a front door.
 *
 * shiftrunner.ca is the desktop home of the app, and the people who type it
 * are not only the crew — head office reads the reports, and Suncor may see
 * the domain in a footer. A lone PIN box on an empty page tells them
 * nothing, so on a wide screen a second column says what this is.
 *
 * The PHONE IS UNCHANGED: everything below is min-width, and .authtell is
 * display:none until 900px. A supervisor signing in at the pit sees exactly
 * the card they saw before.
 * ==================================================================== */
.authtell{display:none;}

@media (min-width:900px){
  .authwrap{
    max-width:1040px;
    display:grid;
    grid-template-columns:1.15fr .85fr;
    gap:64px;
    align-items:center;
    padding:48px 32px;
  }
  /* The pane's own mark is redundant once the left column shows one. */
  .authpane .authmark{display:none;}
  .authpane{width:100%;max-width:400px;}

  .authtell{display:block;}
  .authbrand{display:flex;align-items:center;gap:14px;margin-bottom:22px;}
  .authbrand .mark.big{width:52px;height:52px;margin:0;}
  .authbrand h1{
    font-family:var(--font-display);font-weight:700;font-size:calc(38px * var(--fs));line-height:1;
    letter-spacing:.02em;text-transform:uppercase;margin:0;
  }
  .authlede{
    font-size:calc(17px * var(--fs));line-height:1.55;color:var(--ink-2);margin:0 0 26px;max-width:34em;
  }
  .authpoints{list-style:none;margin:0 0 28px;padding:0;}
  .authpoints li{
    position:relative;padding-left:18px;margin-bottom:13px;
    font-size:calc(14px * var(--fs));line-height:1.5;color:var(--ink-2);max-width:34em;
  }
  /* A red tick of a marker, the same accent the reports and the brand use. */
  .authpoints li::before{
    content:"";position:absolute;left:0;top:8px;
    width:7px;height:7px;border-radius:2px;background:var(--accent-fill);
  }
  .authpoints b{color:var(--ink);font-weight:600;}
}

/* Between tablet and desktop the two columns would squeeze; centre instead. */
@media (min-width:900px) and (max-width:1040px){
  .authwrap{gap:40px;}
  .authlede{font-size:calc(16px * var(--fs));}
}

/* ---- contacts ------------------------------------------------------- */
/* .etext is flex:1 by default, which collapses to its placeholder outside a
   flex row. The search box wants the full width of the card. */
#contact-search{width:100%;}
.crow{
  display:flex;align-items:center;gap:12px;padding:11px 14px;
  border-top:1px solid var(--line);
}
.crow:first-of-type{border-top:0;}
.cmain{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;}
.cmain .lbl{font-size:calc(15px * var(--fs));line-height:1.25;}
.cmain .pmeta{font-size:calc(12px * var(--fs));color:var(--ink-3);}
/* The number is a tel: link — one tap to call from the pit. */
.cphone{
  font-family:var(--font-mono);font-size:calc(13px * var(--fs));color:var(--accent);
  text-decoration:none;align-self:flex-start;
}
.cphone:hover{text-decoration:underline;}
.crow .tag{align-self:flex-start;}
.crow .tag.ok{background:var(--good-soft);color:var(--good);}
.crow .tbtn{flex-shrink:0;}
@media (max-width:420px){
  .crow{flex-direction:column;align-items:stretch;gap:8px;}
  .crow .tbtn{width:100%;}
}

/* ---- wrong-instance warning -------------------------------------- *
 * A copy of the app is indistinguishable from the real one until you
 * look at what is in it, so the copy has to announce itself. Sits in
 * normal flow at the very top of the document: it is the first thing
 * on the sign-in screen, which is the moment the mistake gets made. */
#instancebar{
  /* Sticky, not just first in the document: the sign-in screen is a full
     viewport tall and the browser restores your scroll position, so a bar
     in plain flow is scrolled past before you ever see it. The masthead is
     sticky too, so it is pushed down by the bar's measured height rather
     than sliding underneath and hiding the site name. */
  position:sticky;top:0;z-index:60;
  /* Not var(--danger): that token goes light red in dark mode, and white
     text on it is barely readable. A warning must not get quieter because
     somebody switched theme, so this one colour is fixed in both. */
  background:#B00006;color:#fff;
  padding:10px 14px;text-align:center;
  font:700 .86rem/1.4 var(--font-ui, system-ui, sans-serif);
}
#instancebar span{display:block;font-weight:500;opacity:.93;}
#instancebar a{color:#fff;}
body.hasbar .mast{top:var(--barh,0px);}

/* ============ CAMERA SOURCE SHEET ============
 * Only ever raised in the native builds, where tapping "Take or choose
 * pictures" has to decide between the camera and the library before the OS
 * gets involved. In a browser the file input still does that job and none of
 * this renders.
 *
 * Deliberately a bottom sheet rather than a centre dialog: it appears under a
 * thumb that has just tapped a button near the bottom of a long form, and on
 * a phone held in a glove that is the only part of the screen that is
 * reliably reachable. */
.camsheet{position:fixed;inset:0;z-index:200;display:flex;align-items:flex-end;justify-content:center;}
.camsheet-scrim{position:absolute;inset:0;background:rgba(0,0,0,.45);}
.camsheet-card{
  position:relative;width:100%;max-width:460px;margin:0 8px 8px;
  background:var(--surface);border:1px solid var(--line);border-radius:16px;
  box-shadow:var(--shadow);overflow:hidden;
  /* Clears the home indicator on a modern iPhone. */
  padding-bottom:env(safe-area-inset-bottom,0);
  animation:camsheet-up .16s ease-out;
}
@keyframes camsheet-up{from{transform:translateY(12px);opacity:.6;}to{transform:none;opacity:1;}}
@media (prefers-reduced-motion:reduce){.camsheet-card{animation:none;}}
.camsheet-opt{
  display:block;width:100%;border:0;border-top:1px solid var(--line);
  background:var(--surface);color:var(--ink);
  /* 58px minimum: this is tapped with work gloves on. */
  min-height:58px;padding:12px 16px;text-align:left;cursor:pointer;font:inherit;
}
.camsheet-opt:first-child{border-top:0;}
.camsheet-opt b{display:block;font-size:1rem;font-weight:700;}
.camsheet-opt span{display:block;font-size:.82rem;color:var(--ink-2);margin-top:2px;}
.camsheet-opt:active{background:var(--surface-2);}
.camsheet-opt.cancel{text-align:center;font-weight:700;color:var(--ink-2);}

/* ============ LOCK SCREEN ============
 * Native builds only. Deliberately plain: this is not a sign-in, and it must
 * not read like one — the work is already in there and the supervisor needs
 * to see that at a glance, not wonder whether they have been logged out. */
.lockwrap{
  max-width:380px;margin:0 auto;padding:12vh 20px 40px;
  display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;
}
.lockwrap .mark.big{width:64px;height:64px;}
.lockwrap h1{font:700 1.5rem/1.2 var(--font-display);margin:4px 0 0;}
.locksub{color:var(--ink-2);font-size:.92rem;margin:0 0 6px;}
.lockwrap form{width:100%;margin-top:6px;}
.lockwrap .bigbtn{width:100%;}
.lockwrap .authnote{font-size:.8rem;color:var(--ink-3);margin-top:14px;}

/* ============ SAFE AREAS (notch, Dynamic Island, home indicator) ============
 *
 * Only bites in the native builds. A browser has none of these insets, every
 * value below resolves to 0px, and nothing moves.
 *
 * TWO SOURCES, ONE EXPRESSION. iOS answers env(safe-area-inset-*) natively.
 * Android does NOT: from targetSdk 35 the system forces edge-to-edge, and
 * Capacitor reports the insets by setting --safe-area-inset-* on the root
 * element instead. So each value reads the Android variable FIRST and falls
 * through to the iOS function when it is absent. One expression, both
 * platforms, no platform sniffing.
 *
 * WHY IT IS NEEDED AT ALL: the masthead and the LOCAL COPY bar are
 * position:sticky. A sticky element sticks to the top of the SCROLLPORT, and
 * the scrollport starts behind the status bar — so as soon as the page was
 * scrolled, the bar slid under the clock and the Dynamic Island and became
 * unreadable. Seen happening on an iPhone 17 Pro, not guessed at.
 */
:root{
  --sat: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
  --sab: var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
}

/* The warning bar is the topmost thing when it is up, so it clears the notch. */
#instancebar{ padding-top:calc(10px + var(--sat)); }

/* And the masthead does it when the bar ISN'T up. With the bar present the
   bar has already cleared the notch and .mast is offset below it by --barh,
   so padding here as well would push the whole header down twice. */
.mast-in{ padding-top:calc(11px + var(--sat)); }
body.hasbar .mast-in{ padding-top:11px; }

/* Screens that are not the checklist: no sticky header, but they still start
   at the very top of the display. */
.authwrap, .lockwrap{ padding-top:calc(12vh + var(--sat)); }

/* Sitting on the home indicator otherwise. */
.savebar{ margin-bottom:var(--sab); }
.toast{ bottom:calc(22px + var(--sab)); }

/* ---- scan paperwork ------------------------------------------------ *
 * A page is a PHOTOGRAPH OF A DOCUMENT, so it is shown big enough to tell
 * one page of an FLHA from another at a glance — a 60px thumbnail of a form
 * is a grey rectangle, and the whole reason the arrows exist is that
 * somebody has to be able to see which page is which to put them in order.
 * ------------------------------------------------------------------- */
.scanpages{display:flex;flex-direction:column;gap:12px;}
.scanpage{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--surface-2);}
.scanpage img{
  display:block;width:100%;max-height:340px;object-fit:contain;
  /* White behind it, always: these are photographs of white paper, and on a
     dark background a page with a soft edge looks like it has been cut. */
  background:#fff;
}
/* Until the picture arrives the row would collapse to the bar alone and the
   list would jump as each one loads. */
.scanpage img:not([src]){min-height:180px;}
.scanpage-bar{
  display:flex;align-items:center;gap:6px;padding:8px 10px;
  border-top:1px solid var(--line);background:var(--surface);
  font-size:calc(12px * var(--fs));
}
.scanpage-bar .grow{flex:1;}
.scanpage-bar .ebtn{min-width:38px;padding:6px 8px;font-size:calc(15px * var(--fs));}
.scanpage-bar .ebtn:disabled{opacity:.3;}

.scanfields{display:flex;flex-direction:column;gap:12px;padding:12px 14px;}

/* The chooser. Two lines each — what it is, and who ends up with it — because
   the second one is the part being decided. */
.menulist .tbtn.scanpick{flex-direction:column;align-items:flex-start;gap:2px;}
.scanpick b{display:block;font-weight:700;}
.scanpick span{display:block;font-size:calc(12px * var(--fs));color:var(--ink-2);font-weight:400;}

/* Not red. Nothing has gone wrong — the pages are safe and the document is
   fine; there is simply nobody to send it to yet, and that is a job for the
   general foreman, not an error for the person holding the paper. */
.legend.scanwarn i{background:#d08700;   /* amber, deliberately literal: there is no warning token in the palette and inventing one here would imply the rest of the app uses it */}
.legend.scanwarn span{color:var(--ink-2);}

/* The page, full size, to check it is readable before it goes. */
.scanpage img{cursor:zoom-in;}
.scanpage-bar .hint{font-size:calc(10px * var(--fs));color:var(--ink-3);}
.scanbig{
  position:fixed;inset:0;z-index:60;background:rgba(0,0,0,.92);
  display:flex;align-items:center;justify-content:center;padding:12px;
}
.scanbig img{
  max-width:100%;max-height:100%;object-fit:contain;background:#fff;border-radius:6px;
}
.scanbig .ebtn{position:absolute;top:calc(12px + env(safe-area-inset-top));right:14px;
  background:var(--surface);min-width:44px;min-height:44px;font-size:18px;}

/* A stack, reviewed at a glance. Two columns rather than three: at 375px
   three tiles leave 113px each, which is not enough for a page number and
   the three controls, and a reorder arrow you cannot hit is not a control. */
.scanpages.many{
  display:grid;grid-template-columns:1fr 1fr;gap:10px;
}
.scanpages.many .scanpage img{max-height:150px;}
.scanpages.many .scanpage-bar{padding:6px;gap:2px;font-size:calc(11px * var(--fs));}
.scanpages.many .scanpage-bar .ebtn{min-width:30px;padding:5px 4px;font-size:calc(13px * var(--fs));}
@media (min-width:700px){
  .scanpages.many{grid-template-columns:repeat(4,1fr);}
}

/* The driving tier, beside the approval rather than buried inside it.
   Deliberately not green: a tier is a category, not a pass — "Tier 4" is
   not better or worse than "Tier 1", it is a different thing you may drive. */
.tag.tier{background:var(--surface-3);color:var(--ink-2);border:1px solid var(--line);}

/* "Not approved" is a refusal a supervisor reads before handing over keys.
   In the same grey as every other label it is the one that gets missed. */
.tag.bad{background:var(--danger-soft);color:var(--danger);}

/* ---- the office re-cut the crew chart ---------------------------- *
 * Amber, not red: nothing has gone wrong, but a supervisor who misses this
 * goes to the dump expecting a truck that is now on somebody else's list.
 * It stays on screen until it is acknowledged.
 * ----------------------------------------------------------------- */
.crewnotice{
  border:1px solid #d08700;border-left:4px solid #d08700;border-radius:10px;
  background:var(--surface);padding:12px 14px;margin:0 0 14px;
}
.crewnotice-head{display:flex;align-items:baseline;gap:8px;margin-bottom:8px;}
.crewnotice-head b{font-size:calc(14px * var(--fs));}
.crewline{font-size:calc(13px * var(--fs));line-height:1.45;margin:3px 0;color:var(--ink-2);}
.crewline b{color:var(--ink);font-weight:600;}
/* Taken off reads differently from added — one of them costs him a machine. */
.crewline.out b{color:#d08700;}
.crewnotice .tbtn{margin-top:10px;width:100%;padding:10px;}

/* ---- crew allocation, manager's side ----------------------------- */
.alloclist{display:flex;flex-direction:column;gap:10px;margin-top:10px;}
.allocrow{
  border:1px solid var(--line);border-radius:10px;padding:10px 12px;
  display:grid;grid-template-columns:1fr;gap:8px;background:var(--surface-2);
}
.allocwho b{display:block;font-size:calc(14px * var(--fs));}
.alloccounts{display:flex;gap:6px;flex-wrap:wrap;}
.allocdetail summary{font-size:calc(12px * var(--fs));color:var(--ink-3);cursor:pointer;}
.allocdetail p{margin:6px 0 0;line-height:1.4;}
/* Not red — an unmatched name is a thing to finish, not a failure. */
.legend.warnline i, .warnline{color:var(--ink-2);}
.legend.warnline i{background:#d08700;}
@media (min-width:700px){
  .allocrow{grid-template-columns:1.4fr 1fr auto;align-items:center;}
  .allocdetail{grid-column:1 / -1;}
}
.allocrow .suggest{margin:4px 0 0;color:var(--ink-2);}
.allocrow .suggest b{color:var(--ink);}

/* ---- who owns what, on the allocation tab ------------------------- */
.allocown{padding:12px 14px;margin-bottom:10px;}
.allocown-head{display:flex;align-items:baseline;gap:10px;margin-bottom:10px;}
.allocown-head b{font-size:calc(15px * var(--fs));}
.allocfield{margin:10px 0;}
.allocfield label{
  display:block;font-family:var(--font-mono);font-size:calc(10px * var(--fs));
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);margin-bottom:5px;
}
.allocchips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:6px;}
.allocchip{
  display:inline-flex;align-items:center;gap:5px;
  background:var(--surface-3);border:1px solid var(--line);border-radius:99px;
  padding:4px 6px 4px 10px;font-size:calc(12px * var(--fs));
}
.allocchip .chipx{
  border:0;background:none;color:var(--ink-3);cursor:pointer;
  font-size:calc(12px * var(--fs));line-height:1;padding:2px 4px;
}
.allocchip .chipx:hover{color:var(--danger);}

/* ---- drag a file onto the thing that asks for it ------------------ *
 * The whole panel lights, not just the button: a file dropped near the
 * right place should land, and a target you have to aim at is not much of
 * a target.
 * ----------------------------------------------------------------- */
.dropping{
  outline:2px dashed var(--accent-fill);
  outline-offset:-4px;
  background:color-mix(in srgb, var(--accent-fill) 7%, transparent);
}
/* The children must not steal the drag events from the panel underneath. */
.dropping *{pointer-events:none;}
.drophint{
  display:block;margin-top:6px;text-align:center;
  font-size:calc(11.5px * var(--fs));color:var(--ink-3);
}
@media (hover:none){
  /* A phone has nothing to drag with, so it is not told it can. */
  .drophint{display:none;}
}
