/* netron.css — the design language from the production widgets.
 *
 * Lifted from asknetron/frontend: SocialPublishWidget.dart,
 * GoogleBusinessWidget.dart and social_post_widget.dart, so a page built here
 * looks like the app the owner already uses rather than like a second product.
 *
 * The tokens, counted from those files:
 *   border      #E2E2EA   (16 uses — the single most common colour)
 *   surface     #F7F7FB   (8)
 *   danger      #E0244B   (8)
 *   success     #1FA971   (5)
 *   muted       #92929D   (4)
 *   warning     #F9AB00   (2)
 *   primary     #0062FF
 *   radii       12 / 10 / 8, cards at 16
 *   type        17 heading (w800) · 13.5 label (w700) · 12.5 body · 11.5 small
 *
 * Card = white, radius 16, 1px #E2E2EA, padding 18. Tab = radius 10, padding
 * 9/16, filled primary when active and white with a border when not. Those two
 * shapes carry most of the widget UI, so they carry most of this file.
 */

/* THE PALETTE ABOVE IS HISTORY. The eight names stay -- every rule in this
 * file and in crm.css and promos.css still says var(--nb) -- but they now
 * point at the platform tokens, so the whole dashboard themes from one place
 * and follows the device into dark mode. `--np` was #0062FF, one of the four
 * blues the lock retired.
 *
 * `--np` was also ONE name doing three jobs: 26 text uses, 15 borders, 6
 * fills. No single value is right for all three -- the colour that reads as
 * text on a white card is not the colour a white label sits on. It keeps the
 * text token (safe on a border too) and the fills take `--np-fill`. Same split
 * for danger and success.
 */
@import url("netron-tokens.css");

:root {
  --nb: var(--nt-line);          /* border                      */
  --ns: var(--nt-bg);            /* page surface                */
  --nm: var(--nt-ink-2);         /* muted text                  */
  --np: var(--nt-action-text);   /* primary, as text or border  */
  --np-fill: var(--nt-action);   /* primary, as a fill under white */
  --ng: var(--nt-paid-text);     /* success                     */
  --ng-fill: var(--nt-paid-fill);
  --nd: var(--nt-failed-text);   /* danger                      */
  --nd-fill: var(--nt-failed-fill);
  --nw: var(--nt-waiting-text);  /* warning                     */
  --nt: var(--nt-ink);           /* primary text                */
  /* The three-step elevation scale, copied from the Bookings page
     (reserve.css --rv-sh-*). NET-755: the Bookings page is the design
     reference for the whole console; the flat 1px-outline look predates it. */
  --nt-sh-1: 0 1px 2px rgba(16,18,22,.05), 0 1px 3px rgba(16,18,22,.05);
  --nt-sh-2: 0 2px 6px rgba(16,18,22,.07), 0 8px 24px rgba(16,18,22,.06);
  --nt-sh-3: -10px 0 40px rgba(16,18,22,.18);
}

/* ---- the scope pickers in the top bar ----------------------------------- */
.n-scope{border:1px solid var(--nb);border-radius:8px;padding:5px 9px;
 font-size:12.5px;font-weight:600;color:var(--nt);background:var(--nt-surface);
 font-family:inherit;max-width:190px;margin-left:8px;cursor:pointer}
.n-scope:hover{background:var(--ns)}
.n-scope:focus{outline:none;border-color:var(--np)}

/* ---- shells ------------------------------------------------------------- */
.n-card{background:var(--nt-surface);border:1px solid var(--nb);border-radius:16px;
 padding:18px;box-shadow:var(--nt-sh-1)}
.n-card + .n-card{margin-top:12px}
.n-h{font-size:18px;font-weight:700;color:var(--nt)}
.n-sub{font-size:12.5px;color:var(--nm);margin-top:4px;line-height:1.5}
.n-row{display:flex;align-items:center;gap:10px}
.n-spacer{flex:1}

/* ---- tabs (the period picker, and any segmented control) ----------------
   A raised track with a floating active chip, the Bookings page's segmented
   control (reserve.css .rv-u-tabs). The active tab is surface + action text +
   shadow, never a filled blue block. */
.n-tabs{display:inline-flex;gap:3px;flex-wrap:wrap;margin-bottom:14px;
 padding:3px;background:var(--nt-raised);border-radius:12px}
.n-tab{padding:8px 15px;border-radius:9px;border:1px solid transparent;
 background:transparent;color:var(--nt);font-size:13.5px;font-weight:700;cursor:pointer}
.n-tab:hover{background:color-mix(in oklab, var(--nt-surface) 55%, var(--nt-raised))}
.n-tab.on{background:var(--nt-surface);border-color:var(--nb);
 color:var(--nt-action-text);box-shadow:var(--nt-sh-1)}
.n-tab-n{margin-left:7px;font-size:11.5px;opacity:.75;font-weight:600}

/* ---- buttons ------------------------------------------------------------
   44px floor on every viewport, radius 8 — the Bookings page's .rk-btn.
   The floor used to exist only inside the 760px media block. */
.n-btn{min-height:44px;padding:9px 16px;border-radius:8px;border:1px solid var(--nb);
 background:var(--nt-surface);color:var(--nt);font-size:13.5px;font-weight:700;cursor:pointer}
.n-btn:hover{background:var(--ns)}
.n-btn.pri{background:var(--np-fill);border-color:var(--np);color:#fff;box-shadow:var(--nt-sh-1)}
.n-btn.pri:hover{filter:brightness(1.06)}
.n-btn.ok{background:var(--ng-fill);border-color:var(--ng);color:#fff}
.n-btn.dang{color:var(--nd);border-color:var(--nt-line)}
.n-btn.dang:hover{background:var(--nt-surface)}
.n-btn:disabled{opacity:.5;cursor:default}
.n-btn.sm{min-height:36px;padding:6px 11px;font-size:12.5px;border-radius:8px}

/* ---- table -------------------------------------------------------------- */
.n-table{width:100%;border-collapse:collapse;font-size:12.5px;
 font-variant-numeric:tabular-nums}
.n-table th{text-align:left;font-size:11px;font-weight:700;color:var(--nm);
 text-transform:uppercase;letter-spacing:.04em;padding:9px 10px;
 border-bottom:1px solid var(--nb);white-space:nowrap}
.n-table th.r,.n-table td.r{text-align:right}
.n-table td{border-bottom:1px solid var(--nt-line);vertical-align:top}
/* ONE source of truth for the row padding, all three table families —
   three separate literals is how one silently drifts (see
   docs/solutions/four-copies-of-a-money-formula.md). */
.n-table td,.crm-tbl td,.pr-table td{padding:13px 12px}
.n-clickable-row{cursor:pointer}
.n-table tbody tr.n-clickable-row:hover td,.crm-tbl tbody tr.n-clickable-row:hover td,
.pr-table tbody tr.n-clickable-row:hover td{background:var(--nt-raised)}
.n-clickable-row:focus-visible{outline:2px solid var(--np);outline-offset:-2px}
.n-more-actions{min-width:38px;font-size:18px;line-height:1}
.n-action-menu{position:fixed;z-index:140;min-width:190px;max-width:min(280px,calc(100vw - 16px));
 padding:6px;background:var(--nt-surface);border:1px solid var(--nb);border-radius:10px;
 box-shadow:0 12px 32px rgba(20,28,45,.2)}
.n-action-item{display:block;width:100%;border:0;border-radius:7px;padding:10px 12px;
 background:transparent;color:var(--nt);font:inherit;font-size:13px;font-weight:650;
 text-align:left;cursor:pointer}
.n-action-item:hover,.n-action-item:focus-visible{background:var(--ns);outline:none}
.n-action-item.danger{color:var(--nt-failed-text)}
.n-action-item:disabled{opacity:.45;cursor:not-allowed}
.n-strong{font-weight:700;color:var(--nt);font-size:13px}

/* ---- pills -------------------------------------------------------------- */
.n-pill{display:inline-block;padding:3px 9px;border-radius:8px;font-size:11px;
 font-weight:700;background:var(--nt-bg);color:var(--nm);white-space:nowrap}
.n-pill.ok{background:color-mix(in oklab, var(--nt-paid) 12%, var(--nt-surface));color:var(--ng)}
.n-pill.bad{background:color-mix(in oklab, var(--nt-failed) 12%, var(--nt-surface));color:var(--nd)}
.n-pill.warn{background:color-mix(in oklab, var(--nt-waiting) 18%, var(--nt-surface));color:var(--nw)}
/* PAID is blue, not green: green is "this finished well", and an order can be
   paid and still cancelled. Nihat marked it blue on the drawer (NET-1024). */
.n-pill.info{background:color-mix(in oklab, var(--nt-info-text) 12%, var(--nt-surface));
 color:var(--nt-info-text)}

/* ---- tiles (the number strip at the top of a page) --------------------- */
.n-tiles{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.n-tile{flex:1;min-width:132px;background:var(--nt-surface);border:1px solid var(--nb);
 border-radius:16px;padding:16px 18px;box-shadow:var(--nt-sh-1)}
.n-tile .k{font-size:13px;color:var(--nm);font-weight:650}
.n-tile .v{font-size:27px;font-weight:750;color:var(--nt);margin-top:4px;
 font-variant-numeric:tabular-nums}
.n-tile .v.warn{color:var(--nd)}

/* ---- empty state (the widgets' shape: icon, line, sub-line) ------------ */
.n-empty{text-align:center;padding:26px 10px}
.n-empty .i{font-size:34px;opacity:.35}
.n-empty .t{font-size:13.5px;font-weight:700;color:var(--nt);margin-top:8px}
.n-empty .s{font-size:12.5px;color:var(--nm);margin-top:4px}

/* ---- the recipient picker ---------------------------------------------- */
.n-pick{border:1px solid var(--nb);border-radius:12px;padding:14px;
 background:var(--nt-surface);margin-bottom:12px}
.n-pick-l{font-size:11.5px;color:var(--nm);font-weight:600;margin-bottom:7px}
.n-search{width:100%;border:1px solid var(--nb);border-radius:10px;
 padding:9px 11px;font-size:13px;font-family:inherit;color:var(--nt)}
.n-search:focus{outline:none;border-color:var(--np);
 box-shadow:0 0 0 3px color-mix(in oklab, var(--nt-action) 10%, transparent)}
.n-people{max-height:236px;overflow-y:auto;border:1px solid var(--nb);
 border-radius:10px;margin-top:9px}
.n-person{display:flex;align-items:center;gap:10px;padding:9px 11px;
 border-bottom:1px solid var(--nt-line);cursor:pointer;font-size:12.5px}
.n-person:last-child{border-bottom:none}
.n-person:hover{background:var(--ns)}
.n-person.off{opacity:.45;cursor:not-allowed}
.n-person input{width:15px;height:15px;accent-color:var(--np)}
.n-person .nm{font-weight:700;color:var(--nt)}
.n-person .ct{color:var(--nm);font-size:11.5px}
.n-chosen{display:flex;gap:6px;flex-wrap:wrap;margin-top:9px}
.n-chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px 4px 11px;
 border-radius:999px;background:var(--nt-surface);color:var(--nt-ink);font-size:11.5px;
 font-weight:600}
.n-chip b{cursor:pointer;opacity:.6;font-weight:700}
.n-chip b:hover{opacity:1}

/* ---- social posts ------------------------------------------------------- */
/* Actions live top-right: one row, right-aligned, above everything. */
.so-actions{gap:8px;margin-bottom:12px;flex-wrap:wrap}
.so-conn{padding:13px 15px}
.so-strip{display:flex;gap:22px;flex-wrap:wrap}
.so-chan{display:flex;align-items:center;gap:8px}
.so-cdot{width:8px;height:8px;border-radius:50%;background:var(--nd-fill);
 flex:0 0 auto}
.so-chan.on .so-cdot{background:var(--ng-fill)}
.so-cname{font-size:12.5px;font-weight:700;color:var(--nt);line-height:1.3}
.so-cval{font-size:11.5px;color:var(--nm);line-height:1.3}
/* The post table has eight columns; on a narrow window it scrolls inside its
   own card rather than pushing the page sideways. */
.so-scroll{overflow-x:auto;margin-top:10px}
.so-scroll .n-table{min-width:820px}
.so-thumb{width:40px;height:40px;object-fit:cover;border-radius:6px;
 border:1px solid var(--nb);display:block}

/* ---- the social composer, ported from SocialPublishWidget.dart ---------- */
/* Its own input shape: filled #F7F7FB, radius 12, #E2E2EA border, blue on
   focus, red 1.6px on error — the widget's `dec()` helper, in CSS. */
.so-in{width:100%;background:var(--ns);border:1px solid var(--nb);
 border-radius:12px;padding:12px 14px;font-size:13px;font-family:inherit;
 color:var(--nt);margin-bottom:2px}
.so-in:focus{outline:none;border-color:var(--np);background:var(--nt-surface)}
.so-in.bad{border-color:var(--nd);border-width:1.6px}
.so-in.sm{width:auto;min-width:96px;padding:9px 10px;border-radius:8px;
 margin-bottom:0}
.so-in.xs{width:64px;padding:9px 10px;border-radius:8px;margin-bottom:0}
.so-err{color:var(--nd);font-size:12.5px;font-weight:700;min-height:15px;
 margin-bottom:6px}
.so-lab{display:block;font-size:11.5px;color:var(--nm);font-weight:600;
 margin:10px 0 5px}
.so-lab2{font-size:12.5px;font-weight:600;color:var(--nm);margin-bottom:8px}
.so-lab3{font-size:12.5px;color:var(--nm);margin:10px 0 8px}

/* three crop slots, side by side as in the widget */
.so-slots{display:flex;gap:9px}
.so-slot{flex:1;border:1px solid var(--nb);border-radius:12px;padding:12px 8px;
 text-align:center;cursor:pointer;background:var(--nt-surface);position:relative;
 overflow:hidden}
.so-slot:hover{border-color:var(--np);background:var(--nt-surface)}
.so-slot.filled{padding:0;border-color:var(--np)}
.so-slotr{display:inline-block;background:var(--np-fill);color:#fff;font-size:11px;
 font-weight:700;border-radius:7px;padding:5px 9px;margin-bottom:7px}
.so-slotl{font-size:12px;font-weight:700;color:var(--nt)}
.so-slotd{font-size:10.5px;color:var(--nm)}
.so-slot.filled .so-slotl,.so-slot.filled .so-slotd{padding:0 4px}
.so-slotimg{width:100%;height:82px;object-fit:cover;display:block}
.so-slotx{position:absolute;top:5px;right:5px;border:none;border-radius:50%;
 width:20px;height:20px;background:rgba(0,0,0,.55);color:#fff;cursor:pointer;
 font-size:14px;line-height:1}

/* the schedule box tints blue when it is on — the widget's clearest signal
   that this post repeats rather than going out once */
.so-sched{border:1px solid var(--nb);border-radius:10px;padding:12px;
 background:var(--ns);margin-bottom:12px}
.so-sched.on{background:color-mix(in oklab, var(--nt-action) 5%, transparent);border-color:color-mix(in oklab, var(--nt-action) 40%, transparent)}
.so-schh{font-size:13.5px;font-weight:700;color:var(--nt)}
.so-switch{width:40px;height:22px;border-radius:999px;border:none;
 background:var(--nt-raised);position:relative;cursor:pointer;padding:0}
.so-switch.on{background:var(--np-fill)}
.so-knob{position:absolute;top:3px;left:3px;width:16px;height:16px;
 border-radius:50%;background:var(--nt-surface);transition:left .13s ease}
.so-switch.on .so-knob{left:21px}

.so-editing{display:flex;align-items:center;gap:8px;font-size:12.5px;
 font-weight:700;color:var(--np);margin:8px 0}
.so-cancel{margin-left:auto;font-size:12.5px;color:var(--nm);cursor:pointer;
 text-decoration:underline;font-weight:400}

.so-days{display:flex;gap:6px;flex-wrap:wrap}
.so-days.bad{border:1.6px solid var(--nd);border-radius:10px;padding:6px}
.so-day{padding:7px 11px;border-radius:8px;border:1px solid var(--nb);
 background:var(--nt-surface);font-size:12.5px;font-weight:600;color:var(--nt);cursor:pointer}
.so-day.on{background:var(--np-fill);border-color:var(--np);color:#fff}

.so-when{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:10px}
.so-wl{font-size:12.5px;color:var(--nm)}
.so-sentwrap{background:color-mix(in oklab, var(--nt-action) 8%, transparent);border-radius:8px;padding:10px 12px;
 margin-top:10px;font-size:14.5px;font-weight:700;line-height:1.35;
 color:var(--nt)}
.so-sentwrap b{color:var(--np);font-weight:800}

.so-targets{display:flex;gap:8px;flex-wrap:wrap}
.so-tgt{padding:7px 13px;border-radius:999px;border:1px solid var(--nb);
 background:var(--nt-surface);font-size:12.5px;color:var(--nt);cursor:pointer}
.so-tgt.on{background:color-mix(in oklab, var(--nt-action) 12%, transparent);border-color:var(--np);color:var(--nt-ink);
 font-weight:700}
.so-tgt:disabled{opacity:.45;cursor:default}

/* ---- the four-grid marketing dashboard --------------------------------- */
.md-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
@media (max-width:1100px){.md-grid{grid-template-columns:1fr}}
/* The calendar is the tallest card and the reason the page exists, so it
   anchors the left column and the promotions card sits under it. */
.md-cal{grid-row:span 2}
@media (max-width:1100px){.md-cal{grid-row:auto}}

.md-cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;
 margin-top:12px}
.md-dow{font-size:10.5px;font-weight:700;color:var(--nm);text-transform:uppercase;
 letter-spacing:.04em;text-align:center;padding-bottom:4px}
/* SQUARE cells — aspect-ratio keeps them square at any width, so several
   events fit in a day without the row collapsing. */
.md-day{aspect-ratio:1/1;border:1px solid var(--nb);border-radius:8px;
 padding:4px 5px;overflow:hidden;background:var(--nt-surface);cursor:pointer;
 display:flex;flex-direction:column;gap:2px}
.md-day:hover{border-color:var(--np);background:var(--nt-surface)}
.md-day.out{background:var(--nt-surface);opacity:.5}
.md-day.today{border-color:var(--np);border-width:2px;background:var(--nt-surface)}
.md-daynum{font-size:11px;font-weight:700;color:var(--nt);line-height:1.2}
.md-day.today .md-daynum{color:var(--np)}
.md-day.out .md-daynum{color:var(--nm);font-weight:600}

.md-ev{display:flex;align-items:center;gap:3px;font-size:9.5px;line-height:1.25;
 background:var(--nt-surface);border-radius:4px;padding:1px 3px;overflow:hidden}
.md-ev.mine{background:var(--nt-surface);cursor:pointer}
.md-ev.mine:hover{background:var(--nt-bg)}
.md-evt{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
 color:var(--nt)}
.md-dot{width:6px;height:6px;border-radius:50%;flex:0 0 auto}
.md-more{font-size:9px;color:var(--nm);padding-left:2px}

.md-key{display:flex;gap:11px;flex-wrap:wrap;margin-top:11px;font-size:10.5px;
 color:var(--nm)}
.md-keyi{display:inline-flex;align-items:center;gap:4px}

/* ---- the day panel ------------------------------------------------------
   A day cell tops out at three truncated chips and cannot show a note at all,
   so this is the only place the calendar's own content is readable. */
.md-modal{position:fixed;inset:0;z-index:70;display:none;
 background:rgba(17,24,39,.4);align-items:stretch;justify-content:flex-end}
.md-modal.on{display:flex}
/* A RIGHT-SIDE PANEL, never a centred pop-up.
   A centred dialog covers the list the owner is working from, and it boxes
   wide content — the mapping grid runs to ten columns and simply will not fit
   in one. The panel keeps the list visible beside it and can be as wide as the
   content needs. This is set here once, so every page gets it. */
.md-daybox{background:var(--nt-surface);border-radius:0;width:min(760px,100%);
 height:100%;max-height:100%;display:flex;flex-direction:column;
 box-shadow:-18px 0 48px rgba(0,0,0,.18);animation:md-slide .18s ease-out}
@keyframes md-slide{from{transform:translateX(24px);opacity:.6}
                    to{transform:translateX(0);opacity:1}}
/* A panel holding a mapping grid needs the room; one holding a short form
   does not, so the width follows the content. */
.md-daybox:has(.mg-body),.md-daybox:has(.mp-grid){width:min(1100px,100%)}

/* ---- the panel on a phone ------------------------------------------------
   Full width, and the buttons stay put. A form long enough to scroll — a
   product with six sizes, a mapping with ten rules — used to carry Save away
   with it, so the owner filled the form in and then had to hunt for the button
   at the bottom of a list they had already read. It sits at the foot of the
   screen instead, always in reach of a thumb. */
@media (max-width:760px){
  .md-modal{padding:0}
  .md-daybox{width:100%;max-width:100%}
  .md-dayhead{padding:13px 14px;position:sticky;top:0;background:var(--nt-surface);z-index:2}
  .md-daybody{padding:12px 14px}
  .md-dayfoot{position:sticky;bottom:0;background:var(--nt-surface);
   padding:12px 14px calc(12px + env(safe-area-inset-bottom,0px));
   box-shadow:0 -6px 18px rgba(0,0,0,.06)}
  .md-dayfoot .n-btn{flex:1 1 auto}
  /* The close control must clear the phone's own home indicator and notch. */
  .md-back,.md-x{min-width:44px;min-height:44px}

  /* iOS zooms the whole page in when you focus a field whose text is smaller
     than 16px — you tap Name, the page jumps to 150% and you are now scrolled
     sideways with the field half off-screen. It is not a preference, it is a
     hard threshold in Safari, so every control that can take focus meets it. */
  .n-search,.n-sel,.mp-sel,.mg-num,.pd-search,
  input,select,textarea{font-size:16px}
}
.md-dayhead{display:flex;align-items:center;gap:10px;padding:15px 18px;
 border-bottom:1px solid var(--nb)}
.md-dayhead b{font-size:15.5px}
.md-back,
.md-x{border:none;background:none;font-size:16px;cursor:pointer;color:var(--nm);
 min-width:36px;min-height:36px;font-family:inherit}
.md-back{font-size:24px;line-height:1;padding:0;border-radius:8px}
.md-back:hover,.md-back:focus{background:var(--nt-surface-2);color:var(--nt)}
.md-daybody{padding:14px 18px;overflow-y:auto;overflow-x:hidden;flex:1 1 auto}
.md-dayrow{display:flex;gap:11px;width:100%;text-align:left;background:none;
 border:none;border-bottom:1px solid var(--nt-line);padding:12px 8px;
 font-family:inherit;align-items:stretch}
.md-dayrow:last-child{border-bottom:none}
button.md-dayrow{cursor:pointer}
button.md-dayrow:hover{background:var(--nt-surface)}
.md-daybar{width:3px;border-radius:99px;flex:0 0 auto}
.md-daymid{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:3px}
.md-daytop{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
/* Fixed width so titles line up whether or not an entry has a time. */
.md-daytime{font-size:11.5px;font-weight:700;color:var(--np);flex:0 0 auto;
 min-width:52px}
.md-daytitle{font-size:14px;font-weight:600;color:var(--nt)}
.md-daynote{font-size:12.5px;color:var(--nt-ink);line-height:1.45;white-space:pre-wrap}
.md-dayby{font-size:10.5px;color:var(--nm)}
.md-dayrow.ro .md-daytitle{color:var(--nt-ink)}
.md-dayedit{font-size:11.5px;font-weight:700;color:var(--np);align-self:center;
 flex:0 0 auto}
.md-dayfoot{display:flex;gap:9px;padding:13px 18px;border-top:1px solid var(--nb);
 flex-wrap:wrap}
.md-when{display:flex;gap:8px}
.md-when input[type=date]{flex:1 1 auto;max-width:200px}
.md-when input[type=time]{flex:0 0 auto;max-width:130px}

/* ---- the week ahead ----------------------------------------------------- */
.md-soon{margin-bottom:12px}
.md-soon-strip{display:flex;flex-direction:column;margin-top:10px}
.md-soon-row{display:flex;align-items:center;gap:12px;padding:10px 2px;
 border-bottom:1px solid var(--nt-line)}
.md-soon-row:last-child{border-bottom:none}
.md-soon-when{flex:0 0 auto;width:96px;display:flex;flex-direction:column}
.md-soon-d{font-size:12.5px;font-weight:700;color:var(--nt)}
.md-soon-t{font-size:10.5px;color:var(--nm)}
.md-soon-mid{flex:1 1 auto;min-width:0}
.md-soon-ti{display:flex;align-items:center;gap:6px;font-size:13.5px;
 font-weight:600;color:var(--nt)}
.md-soon-n{font-size:11.5px;color:var(--nm);margin-top:2px;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- the month as a list, on phones -------------------------------------- */
.md-agenda{display:flex;flex-direction:column;gap:9px;margin-top:10px}
.md-ag-day{border:1px solid var(--nb);border-radius:11px;overflow:hidden}
.md-ag-day.today{border-color:var(--np);border-width:2px}
.md-ag-head{display:flex;align-items:center;gap:9px;width:100%;border:none;
 background:var(--nt-surface);padding:9px 12px;cursor:pointer;font-family:inherit;
 min-height:44px;text-align:left}
.md-ag-num{font-size:16px;font-weight:800;color:var(--nt)}
.md-ag-dow{font-size:11.5px;color:var(--nm);flex:1 1 auto}
.md-ag-n{font-size:10.5px;font-weight:700;color:var(--np)}
.md-ag-evs{display:flex;flex-direction:column}
.md-ag-ev{display:flex;align-items:center;gap:7px;width:100%;border:none;
 background:none;padding:10px 12px;border-top:1px solid var(--nt-line);cursor:pointer;
 font-family:inherit;text-align:left;min-height:42px}
.md-ag-t{font-size:11px;font-weight:700;color:var(--np);flex:0 0 auto}
.md-ag-ti{font-size:13px;color:var(--nt);overflow:hidden;
 text-overflow:ellipsis;white-space:nowrap}

.md-act{display:flex;gap:9px;align-items:flex-start;padding:8px 0;
 border-bottom:1px solid var(--nt-line)}
.md-act:last-child{border-bottom:none}
.md-acti{font-size:15px;flex:0 0 auto;line-height:1.3}
.md-actt{font-size:12.5px;color:var(--nt)}

/* ---- order detail drawer body ------------------------------------------ */
.n-kv{display:flex;justify-content:space-between;gap:14px;padding:7px 0;
 font-size:12.5px;border-bottom:1px solid var(--nt-line)}
.n-kv:last-child{border-bottom:none}
.n-kv .k{color:var(--nm)}
.n-kv .v{color:var(--nt);font-weight:600;text-align:right}
.n-line{display:flex;justify-content:space-between;gap:12px;padding:9px 0;
 border-bottom:1px solid var(--nt-line);font-size:12.5px}
.n-line:last-child{border-bottom:none}
.n-line .q{color:var(--nm);min-width:26px;font-weight:700}
.n-line .mods{color:var(--nm);font-size:11.5px;margin-top:3px;line-height:1.5}
/* A VOIDED line: rung up, then taken off. The kitchen never cooked it and the
   customer never paid for it, and the till bill prints it struck through
   (NET-842). Red carries the alarm, the strike carries the meaning, and the
   VOIDED pill carries both to a reader who gets neither — colour alone is not
   a label. (NET-1014) */
.n-line.void, .n-line.void .q, .n-line.void .mods{color:var(--nd)}
.n-line.void .nm, .n-line.void .amt{text-decoration:line-through}
.n-line.void .n-pill{margin-top:5px}
.n-tot{display:flex;justify-content:space-between;font-size:15px;font-weight:800;
 color:var(--nt);padding-top:11px;margin-top:4px;border-top:2px solid var(--nb)}

/* the calendar legend is by AUTHOR, and NetronAi is called out as shared */
.md-keyi.na{font-weight:700;color:var(--nt)}
.md-ro{font-size:9.5px;color:var(--nm);font-weight:400;
 background:var(--nt-bg);border-radius:5px;padding:1px 5px;margin-left:3px}

/* ---- customer tags ------------------------------------------------------ */
.tg-chip{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;
 border-radius:999px;background:var(--nt-bg);color:var(--nt);font-size:11.5px;
 font-weight:600;margin:2px 4px 2px 0}
.tg-dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto}
.tg-chip b{cursor:pointer;opacity:.5;font-weight:700;margin-left:1px}
.tg-chip b:hover{opacity:1;color:var(--nd)}
/* "Filled by a rule". A WORD, not a glyph and not a colour — an icon names
   nothing to a screen reader or to a member of staff nobody has briefed, and
   colour alone is not a distinction every reader can make. */
.tg-auto{font-size:9.5px;font-weight:700;letter-spacing:.04em;
 text-transform:uppercase;padding:1px 5px;border-radius:999px;
 background:var(--nt-raised);color:var(--nt-ink);cursor:help}
/* the tag type-ahead */
.tg-ta{position:relative;display:inline-block}
.tg-in{border:1px dashed var(--nb);border-radius:999px;padding:4px 11px;
 font-size:11.5px;color:var(--nt);background:var(--nt-surface);font-family:inherit;
 width:150px;outline:none}
.tg-in:focus{border-style:solid;border-color:var(--np)}
.tg-in::placeholder{color:var(--nm)}
.tg-menu{display:none;position:absolute;top:calc(100% + 4px);left:0;z-index:20;
 min-width:230px;max-height:240px;overflow-y:auto;background:var(--nt-surface);
 border:1px solid var(--nb);border-radius:10px;
 box-shadow:0 8px 26px rgba(0,0,0,.12)}
.tg-menu.on{display:block}
.tg-opt{display:flex;align-items:center;gap:7px;padding:8px 11px;
 font-size:12.5px;color:var(--nt);cursor:pointer}
.tg-opt:hover,.tg-opt.on{background:var(--ns)}
.tg-opt.tg-new{border-top:1px solid var(--nt-line);color:var(--np);font-weight:600}
.tg-n{margin-left:auto;font-size:10.5px;color:var(--nm);font-weight:400}
.tg-none{padding:9px 11px;font-size:12px;color:var(--nm)}
.tg-pal{display:flex;gap:7px;flex-wrap:wrap}
.tg-sw{width:26px;height:26px;border-radius:50%;border:2px solid transparent;
 cursor:pointer}
.tg-sw.on{border-color:var(--nt);transform:scale(1.12)}

/* ---- the customer chat thread ------------------------------------------- */
.th-stream{max-height:44vh;overflow-y:auto;padding:4px 2px 10px;
 display:flex;flex-direction:column;gap:9px}
.th-row{display:flex}
.th-row.mine{justify-content:flex-end}
.th-bub{max-width:78%;background:var(--nt-bg);border-radius:12px;padding:9px 12px}
.th-bub.mine{background:var(--nt-surface)}
.th-body{font-size:13px;color:var(--nt);line-height:1.45;white-space:pre-wrap;
 word-break:break-word}
.th-meta{font-size:10.5px;color:var(--nm);margin-top:5px}

.th-chans{display:flex;gap:7px;flex-wrap:wrap;margin:10px 0 8px}
.th-ch{padding:7px 12px;border-radius:999px;border:1px solid var(--nb);
 background:var(--nt-surface);font-size:12.5px;font-weight:600;color:var(--nt);
 cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.th-ch.on{background:var(--np-fill);border-color:var(--np);color:#fff}
.th-ch:disabled{opacity:.5;cursor:default}
.th-why{font-size:10.5px;font-weight:400;opacity:.85}
.th-comp{border-top:1px solid var(--nb);padding-top:10px}
.th-ta{resize:vertical;font-family:inherit}

/* ---- event cards in the thread (NET-802) --------------------------------
   An order or a booking, at its place in time. Rendered by thread.js only
   when a caller hands it events — the CRM Chat tab passes none and is
   untouched. */
.th-card{max-width:82%;background:var(--nt-surface);border:1px solid var(--nb);
 border-radius:12px;padding:9px 12px;display:flex;gap:10px;align-items:center}
.th-cico{width:32px;height:32px;border-radius:9px;display:flex;
 align-items:center;justify-content:center;font-size:15px;flex:none;
 background:var(--nt-raised)}
.th-cbody{min-width:0;flex:1}
.th-cttl{font-weight:650;font-size:12.5px;color:var(--nt)}
.th-cdtl{font-size:11.5px;color:var(--nt-ink-2)}
.th-copen{color:var(--np);font-size:12px;cursor:pointer;white-space:nowrap;
 background:none;border:none;font-family:inherit;padding:4px}
.th-cardrun{font-size:12px;color:var(--nt-ink-2);border:1px dashed var(--nb);
 border-radius:12px;padding:7px 12px;cursor:pointer;max-width:82%}
.th-cardrun:hover{background:var(--nt-raised)}

/* ---- the customer inbox — the Chat page (NET-802) ----------------------- */
#p-inbox .th-stream{max-height:none;flex:1 1 auto}
.ib-wrap{display:grid;grid-template-columns:305px minmax(0,1fr);
 border:1px solid var(--nb);border-radius:14px;background:var(--nt-surface);
 overflow:hidden;box-shadow:var(--nt-sh-1);height:calc(100vh - 155px);
 min-height:480px}
.ib-list{border-right:1px solid var(--nb);display:flex;flex-direction:column;
 min-width:0}
.ib-search{margin:10px 10px 8px}
.ib-rows{overflow-y:auto;flex:1}
.ib-row{display:flex;gap:10px;padding:11px 13px;cursor:pointer;
 border-bottom:1px solid var(--nt-line);align-items:center}
.ib-row:hover{background:var(--nt-raised)}
.ib-row.on{background:var(--nt-bg)}
.ib-av{width:38px;height:38px;border-radius:50%;flex:none;display:flex;
 align-items:center;justify-content:center;font-weight:700;font-size:13px;
 color:#fff}
.ib-meta{min-width:0;flex:1}
.ib-top{display:flex;align-items:baseline;gap:6px}
.ib-name{font-weight:650;font-size:13.5px;white-space:nowrap;overflow:hidden;
 text-overflow:ellipsis;color:var(--nt)}
.ib-time{margin-left:auto;font-size:10.5px;color:var(--nm);flex:none}
.ib-prev{display:flex;align-items:center;gap:5px;font-size:12px;
 color:var(--nt-ink-2);white-space:nowrap;overflow:hidden}
.ib-prev span{overflow:hidden;text-overflow:ellipsis}
.ib-badge{background:var(--np);color:#fff;font-size:10.5px;font-weight:700;
 border-radius:999px;min-width:18px;height:18px;display:inline-flex;
 align-items:center;justify-content:center;padding:0 5px;flex:none}
.ib-badge:empty{display:none}
.ib-thread{display:flex;flex-direction:column;min-width:0}
.ib-head{display:flex;align-items:center;gap:10px;padding:10px 14px;
 border-bottom:1px solid var(--nb)}
.ib-head .ib-av{width:32px;height:32px;font-size:12px}
.ib-who{min-width:0;flex:1}
.ib-wname{font-weight:700;font-size:14px;color:var(--nt)}
.ib-wsub{font-size:11px;color:var(--nm)}
.ib-back{display:none;border:none;background:none;font-size:20px;
 cursor:pointer;color:var(--np);padding:2px 8px;font-family:inherit}
.ib-filters{display:flex;gap:6px;padding:8px 14px;
 border-bottom:1px solid var(--nt-line);align-items:center;overflow-x:auto;
 scrollbar-width:none}
.ib-filters::-webkit-scrollbar{display:none}
.ib-body{flex:1;display:flex;flex-direction:column;overflow:hidden;
 padding:10px 14px}
.ib-quiet{flex:1;display:flex;flex-direction:column;gap:6px;
 align-items:center;justify-content:center;color:var(--nm);font-size:13px;
 text-align:center;padding:30px}
.ib-quiet .i{font-size:26px}
/* filter chips hide kinds; the classes sit on the page so thread.js stays
   filter-unaware */
#p-inbox.ibf-msg .th-card,#p-inbox.ibf-msg .th-cardrun{display:none}
#p-inbox.ibf-order .th-row,
#p-inbox.ibf-order .th-card[data-k="booking"]{display:none}
#p-inbox.ibf-booking .th-row,
#p-inbox.ibf-booking .th-card[data-k="order"]{display:none}
/* phone: one pane at a time — the list first, the thread with a back control */
body.mb .ib-wrap{grid-template-columns:1fr;height:calc(100vh - 175px)}
body.mb .ib-wrap.open .ib-list{display:none}
body.mb .ib-wrap:not(.open) .ib-thread{display:none}
body.mb .ib-back{display:block}

/* ═══ SETTINGS HUB ═════════════════════════════════════════════════════════
   Company · Location · Your Profile. Shaped after the v1 Location Billing tab
   so it is familiar, with the money laid out to be read rather than decoded. */
.st-tabs{margin-bottom:14px;overflow-x:auto;scrollbar-width:none}
.st-tabs::-webkit-scrollbar{display:none}
/* The Location AND Company sub-tabs sit on their own row under
   Company · Location · Your Profile (Nihat, 2026-09-06), never inline to the
   right of them. One rule, two selectors — the Company row was given its own
   copy of this once and immediately drifted, which is the shape
   `docs/solutions/four-copies-of-a-money-formula.md` is about. */
.st-location-tabs,
.st-company-tabs{display:flex;width:fit-content;max-width:100%;margin:0 0 14px;overflow-x:auto;scrollbar-width:none}
.st-location-tabs::-webkit-scrollbar,
.st-company-tabs::-webkit-scrollbar{display:none}
/* Billing & Wallet (NET-981): the strip under the wallet and the card, the
   tabs inside Billing History, and the filter bar above each list. */
.st-billing-tabs{display:flex;width:fit-content;max-width:100%;margin:2px 0 14px;
 overflow-x:auto;scrollbar-width:none}
.st-billing-tabs::-webkit-scrollbar{display:none}
.st-history-tabs{display:flex;width:fit-content;max-width:100%;margin-bottom:12px}
.st-filter{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin:6px 0 12px}
.st-filter-label{font-size:10px;font-weight:800;text-transform:uppercase;color:var(--nt-ink-2)}
.st-chips{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap}
.st-chip{padding:5px 11px;border-radius:999px;border:1px solid var(--nb);background:transparent;
 font:inherit;font-size:12.5px;font-weight:700;cursor:pointer;color:inherit}
.st-chip.on{background:var(--nt-surface);border-color:var(--nt);color:var(--nt)}
.st-filter input[type=date]{max-width:150px}
.st-agreement{margin:4px 0 14px}
.st-agreement-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin:6px 0 8px;font-weight:700}
.st-agreement-head .n-sub{font-weight:500}
.st-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start;
 margin-bottom:12px}
@media (max-width:900px){.st-grid{grid-template-columns:1fr}}
.st-amount{font-size:34px;font-weight:800;color:var(--nt);margin:6px 0 2px}
.st-topup{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;align-items:center}
.st-other{max-width:110px}
.st-auto{display:flex;gap:9px;align-items:center;flex-wrap:wrap;
 margin-top:14px;padding-top:12px;border-top:1px solid var(--nb)}
.st-switch{display:inline-flex;align-items:center;gap:7px;font-size:13.5px;
 font-weight:700;cursor:pointer}
.st-thr{max-width:90px}
.st-warn{font-size:12.5px;color:var(--nt-failed-text);background:color-mix(in oklab, var(--nt-failed) 12%, var(--nt-surface));
 border:1px solid var(--nt-line);border-radius:9px;padding:8px 11px;margin:9px 0}

/* the typed-card form — only on screen while the hosted page is down */
.st-cardform{margin-top:12px;padding-top:11px;border-top:1px solid var(--nb)}
.st-cardform .n-search{margin-bottom:9px}
.st-cardform .n-pick-l{margin-top:4px}

/* the card face — the one bit of v1 worth copying verbatim */
.st-card{background:var(--nt-ground);color:#fff;border-radius:14px;padding:16px 18px;
 margin:10px 0 12px;max-width:340px}
.st-card.dead{opacity:.55}
.st-card-brand{font-size:12px;font-weight:800;letter-spacing:.08em;
 text-transform:uppercase;opacity:.75}
.st-card-num{font-size:19px;letter-spacing:.12em;margin:14px 0 12px;
 font-family:ui-monospace,Consolas,monospace}
.st-card-foot{display:flex;justify-content:space-between;font-size:11.5px;
 opacity:.8}
.st-cardrow{display:flex;gap:8px}
.st-cardrow input{flex:1 1 0;min-width:0}

.st-form{max-width:560px}
/* Money leaving is red and money arriving is green — the whole point of this
   page is that a spend is visible, which is exactly what v1 gets wrong. */
.st-out{color:var(--nt-failed-text);font-weight:700;text-align:right}
.st-in{color:var(--nt-paid-text);font-weight:700;text-align:right}

/* ═══ MOBILE ═══════════════════════════════════════════════════════════════
   Everything below only applies at phone width. Desktop is untouched — the
   console had four media queries and one of them hid the only navigation, so
   the rule here is additive: nothing above the breakpoint changes. */

/* ---- the bottom tab bar ------------------------------------------------- */
.mb-bar{display:none}
body.mb .mb-bar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:80;
 background:var(--nt-surface);border-top:1px solid var(--nb);
 /* Clear the iOS home indicator, or the last row of every page sits under it */
 padding-bottom:env(safe-area-inset-bottom,0)}
.mb-tab{flex:1;border:none;background:none;padding:8px 2px 7px;cursor:pointer;
 display:flex;flex-direction:column;align-items:center;gap:2px;
 /* R4: 44px is the smallest a thumb reliably hits */
 min-height:52px;color:var(--nm);font-family:inherit}
.mb-tab.on{color:var(--np)}
.mb-ic{font-size:19px;line-height:1}
.mb-lb{font-size:10px;font-weight:700;letter-spacing:.01em}

/* The page has to end above the bar, not behind it. */
body.mb .main{padding-bottom:calc(64px + env(safe-area-inset-bottom,0))}

/* A full-screen editor owns the screen while it is open. The mobile bar is
   z-index 80; leaving the shared editor at 70 drew the bar over its sticky
   Cancel / Save footer and intercepted both taps. */
body.mb .md-modal{z-index:85}

/* The bar is fixed at z-index 80; the customer drawer and sheet are at 60. So
   the bar sits ON TOP of them, and whatever is last inside — the Chat tab's
   composer, a drawer's Save button — is underneath it. Padding on `.main` does
   not help: these are fixed overlays, not children of `.main`. */
body.mb .crm-sheet-body,body.mb .crm-drawer-body{
 padding-bottom:calc(18px + 64px + env(safe-area-inset-bottom,0))}

/* ---- typing ------------------------------------------------------------
   While a field is focused the on-screen keyboard takes half the screen, and
   a 64px navigation bar between the composer and the keyboard is 64px of the
   wrong thing. Hide the bar for as long as the caret is in a field; blurring
   brings it straight back. `body.kb` is set by mobile.js on focusin. */
body.mb.kb .mb-bar{display:none}
body.mb.kb .main{padding-bottom:0}
body.mb.kb .crm-sheet-body,body.mb.kb .crm-drawer-body{padding-bottom:14px}

/* ---- the Send / More sheets -------------------------------------------- */
.mb-sheet-wrap{display:none}
.mb-sheet-wrap.on{display:block;position:fixed;inset:0;z-index:90}
.mb-scrim{position:absolute;inset:0;background:rgba(17,24,39,.35)}
.mb-sheet{position:absolute;left:0;right:0;bottom:0;background:var(--nt-surface);
 border-radius:18px 18px 0 0;padding:8px 12px
 calc(14px + 64px + env(safe-area-inset-bottom,0));
 box-shadow:0 -10px 40px rgba(0,0,0,.18);animation:mbUp .16s ease-out}
@keyframes mbUp{from{transform:translateY(18px);opacity:.5}
 to{transform:translateY(0);opacity:1}}
.mb-grab{width:36px;height:4px;border-radius:99px;background:var(--nt-raised);margin:4px auto 10px}
.mb-title{font-size:12px;font-weight:700;color:var(--nm);text-transform:uppercase;
 letter-spacing:.05em;padding:0 4px 6px}
.mb-sheet-back{min-height:40px;margin:0 0 2px;padding:6px 8px;border:0;
 border-radius:8px;background:transparent;color:var(--np);font:700 13px/1 inherit;
 cursor:pointer}
.mb-sheet-back:hover,.mb-sheet-back:focus{background:var(--nt-surface-2)}
.mb-item{display:flex;align-items:center;gap:12px;width:100%;border:none;
 background:none;padding:13px 6px;cursor:pointer;text-align:left;
 border-top:1px solid var(--nt-line);font-family:inherit;min-height:56px}
.mb-iic{font-size:20px;flex:0 0 auto}
.mb-il{display:block;font-size:14px;font-weight:700;color:var(--nt)}
.mb-ih{display:block;font-size:11.5px;color:var(--nm);margin-top:2px}

/* ---- Settings launcher --------------------------------------------------
   A phone has no sidebar. This strip is shown throughout Settings on both
   layouts. Configuration fills two horizontally scrollable rows that preserve
   the sidebar order without squeezing labels. Company, Location and Your
   Profile remain the three clear tabs inside the Settings page itself. */
.settings-launcher{display:none;flex:0 0 auto;padding:10px 18px 11px;
 border-bottom:1px solid var(--nt-line);background:var(--nt-surface)}
/* Desktop already has the complete Settings sidebar. Duplicating the same
   destinations above the page costs a full row of working space and gives the
   owner two competing navigation controls. The launcher replaces that hidden
   sidebar on phones only. */
body.mb.nav-settings .settings-launcher{display:block}
.set-launch-label{margin:1px 0 6px;color:var(--nt-ink-2);font-size:10.5px;
 font-weight:800;text-transform:uppercase;letter-spacing:.05em}
.set-launch-configs{overflow-x:auto;padding-bottom:4px;scrollbar-width:thin;
 overscroll-behavior-x:contain}
.set-launch-track{display:flex;flex-direction:column;gap:6px;width:max-content;
 min-width:100%}
.set-launch-row{display:flex;gap:7px;width:max-content;min-width:100%}
.set-launch-button{display:inline-flex;align-items:center;gap:6px;min-height:40px;
 padding:8px 12px;border:1px solid var(--nt-line);border-radius:9px;
 background:var(--nt-surface);color:var(--nt);font:700 12px/1.15 inherit;
 white-space:nowrap;cursor:pointer}
.set-launch-button:hover,.set-launch-button:focus{border-color:var(--np);
 background:var(--nt-surface-2);color:var(--np)}
.set-launch-button.on{border-color:var(--np);background:var(--np);color:#fff}
.set-launch-button.soon{opacity:.55;cursor:not-allowed}
.set-launch-icon{font-size:14px}

/* ---- tables become cards ------------------------------------------------
   A 7-to-10 column table cannot survive 390px, and horizontal scroll hides the
   columns that matter. Each row stacks instead, with the header injected as a
   label via data-l so no markup changes are needed per table. */
@media (max-width:760px){
  .settings-launcher{padding:8px 10px 9px}
  .set-launch-button{min-height:44px;padding:9px 12px;font-size:12.5px}
  .n-table thead,.crm-tbl thead,.pr-table thead{display:none}
  .n-table tbody tr,.crm-tbl tbody tr,.pr-table tbody tr{display:block;background:var(--nt-surface);
   border:1px solid var(--nb);border-radius:12px;margin-bottom:9px;padding:4px 2px}
  .n-table td,.crm-tbl td,.pr-table td{display:flex;justify-content:space-between;
   align-items:baseline;gap:12px;border:none;padding:6px 12px;text-align:right}
  .n-table td::before,.crm-tbl td::before,.pr-table td::before{content:attr(data-l);
   font-size:10.5px;font-weight:700;color:var(--nm);text-transform:uppercase;
   letter-spacing:.04em;text-align:left;flex:0 0 auto}
  .n-table td:empty,.crm-tbl td:empty,.pr-table td:empty{display:none}
  /* The customer card: the name reads first, and the reach actions become
     labelled full-width buttons — Send SMS / Send Email are what spend the
     wallet, so they are never clipped or hidden behind an overflow. */
  .crm-tbl td.crm-name{font-size:15px}
  .crm-tbl td.crm-act{justify-content:flex-start;gap:8px;padding:10px 12px 8px}
  .crm-reach{flex:1;display:inline-flex;align-items:center;justify-content:center;
   gap:7px;min-height:44px;font-weight:700;color:var(--nt-action-text);
   border-color:color-mix(in oklab, var(--nt-action) 34%, var(--nt-surface))}
  /* The social table dropped its forced width — it stacks now instead. */
  .so-scroll{overflow-x:visible}
  .so-scroll .n-table{min-width:0}

  /* drawers become pages: a 94vw panel over a 6vw sliver is neither */
  .crm-drawer,.crm-sheet{width:100vw;max-width:100vw;border-radius:0}
  .crm-drawer-body,.crm-sheet-body{padding:14px 13px}
  body.mb .crm-drawer-foot{padding-bottom:calc(14px + env(safe-area-inset-bottom,0))}

  /* R4 — thumbs, not mice */
  .n-btn{padding:11px 16px;min-height:44px}
  .n-btn.sm{padding:9px 13px;min-height:40px;font-size:12.5px}
  .n-tab{padding:11px 15px;min-height:44px}
  .crm-reach{padding:8px 12px;min-height:44px}
  .tg-chip b{padding:0 4px}

  /* the top bar: title above, scope pickers on their own line */
  .top{flex-wrap:wrap;gap:6px}
  .loc{width:100%;display:flex;gap:6px}
  .n-scope{margin-left:0;flex:1;max-width:none}

  /* the calendar: 7 squares at 50px each is unreadable, so let the cells grow
     taller than they are wide rather than shrinking the text */
  .md-day{aspect-ratio:auto;min-height:66px}
  .md-evt{font-size:8.5px}
  .n-tiles{gap:8px}
  .n-tile{min-width:0;flex:1 1 46%}

  /* the chat thread: leave room for the keyboard */
  .th-stream{max-height:38vh}
}

/* ---- shared phone audit -------------------------------------------------
   These rules are intentionally attached to shared primitives, not page ids:
   every current Settings page and every future kit page inherits the same
   readable spacing, scrolling tabs, reachable actions and full-screen editor. */
@media (max-width:760px){
  body.mb .page{max-width:100%;padding:12px;overflow-x:hidden}
  body.mb #p-chat{padding:0}
  body.mb .top{padding:8px 12px;gap:7px;background:var(--nt-surface)}
  body.mb .top b{font-size:15px}
  body.mb .top .loc{min-width:0;overflow:hidden;flex-wrap:nowrap}
  body.mb .wchip{min-height:40px;padding:8px 10px}
  body.mb .n-scope{min-width:0;min-height:40px;padding:8px 28px 8px 9px}

  body.mb h2{font-size:18px;line-height:1.25}
  .n-h{font-size:18px;line-height:1.25}
  .n-sub{font-size:13px;line-height:1.45}
  .n-card{padding:13px;border-radius:13px}
  .n-pick,.crm-panel{padding:12px}
  .n-row{min-width:0}
  .kit-page-head{align-items:flex-start;flex-wrap:wrap;gap:8px}
  .kit-page-head>.n-spacer{display:none}
  .kit-page-head>.n-btn{margin-left:auto}
  .kit-body{min-width:0;margin-top:12px}

  /* Tabs stay one line. Wrapping a four-tab editor into two rows makes its
     current section harder to find and consumes scarce drawer height. */
  .n-tabs,.crm-tabs,.crm-tabbar{max-width:100%;flex-wrap:nowrap;overflow-x:auto;
   overscroll-behavior-x:contain;scrollbar-width:thin;padding-bottom:3px}
  .n-tab,.crm-tab,.crm-tabchip{flex:0 0 auto;white-space:nowrap}

  .crm-head{flex-direction:column;align-items:stretch;gap:10px}
  .crm-head .n-btn,.crm-head .crm-primary{align-self:flex-start}
  .crm-bar{align-items:stretch}
  .crm-bar input[type=text],.crm-bar input:not([type]){min-width:0;width:100%;
   min-height:44px;font-size:16px}
  .crm-pager{justify-content:flex-start;max-width:100%;overflow-x:auto}
  .crm-page-btn{min-height:40px;white-space:nowrap}

  .crm-sheet-top,.crm-drawer-top{padding:8px 10px;gap:6px}
  .crm-sheet-top{justify-content:flex-start}
  .crm-sheet-top b,.crm-drawer-top b{flex:1 1 auto;min-width:0;font-size:15px;
   overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .crm-x{min-width:44px;min-height:44px;padding:0}
  .crm-drawer-foot{justify-content:flex-start;flex-wrap:wrap;gap:8px;
   padding:10px 12px calc(10px + env(safe-area-inset-bottom,0px))}
  .crm-drawer-msg{order:3;flex:1 0 100%;min-height:0}
  #tg-drawer-actions,#cal-drawer-actions,#so-drawer-actions,#pr-drawer-actions{
   justify-content:flex-start!important;flex-wrap:wrap}
  .crm-primary,.crm-ghost,.crm-danger{min-height:44px}

  .md-dayhead b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .md-dayfoot{justify-content:flex-start}
  .md-dayfoot>.n-spacer{display:none}
  .md-dayfoot .n-btn{flex:0 1 auto}
  .md-when{flex-wrap:wrap}
  .md-when input[type=date],.md-when input[type=time]{max-width:none;min-width:0}

  /* Product Pricing and Price List remain comparison grids. Their first
     identifying column stays visible while order-method columns scroll. */
  .pd-matrix-scroll,.pd-overrides-scroll,.pl-grid-scroll{
   max-width:100%;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
   scrollbar-width:thin;touch-action:pan-x pan-y}
  .pd-matrix th:first-child,.pd-matrix td:first-child{position:sticky;left:0;
   z-index:2;background:var(--nt-surface);box-shadow:1px 0 0 var(--nt-line)}
  .pd-matrix th:first-child{z-index:4;background:var(--ns)}
  .pd-price-v2>.n-row{align-items:flex-start;flex-wrap:wrap}
  .pd-price-v2>.n-row>.n-spacer{display:none}
  .pd-scope-choices{flex-wrap:nowrap;overflow-x:auto;padding-bottom:3px;
   scrollbar-width:thin}
  .pd-scope-chip{min-height:44px;flex:0 0 auto}
  .pd-price-actions{justify-content:flex-start}
  .pd-price-actions>.n-spacer{display:none}
  .pd-picture-row{flex-wrap:wrap}
  .pd-picture-controls{flex:1 1 150px}

  .pr-rail{max-width:100%;overflow-x:auto;scrollbar-width:thin}
  .pr-dotwrap,.pr-bar{flex:0 0 auto}
  .pr-row{align-items:stretch;flex-wrap:wrap}
  .pr-row .pr-in{min-width:0}
  .pr-mini{min-height:40px;margin:2px}
  .n-action-item{min-height:44px;font-size:14px}

  /* Tables composed by Chat are data too. Keep short tables full width and
     allow genuinely wide answers to scroll within the message bubble. */
  .ob.wide{max-width:100%;overflow-x:auto;overscroll-behavior-x:contain}
  .ob.wide table{width:max-content;min-width:100%}

  .st-topup,.st-auto,.st-cardrow{align-items:stretch}
  .st-other{max-width:none;min-width:120px;flex:1}
  .st-card{max-width:100%}
  .st-fact{align-items:flex-start}
}

/* ── Price List ────────────────────────────────────────────────────────────
   A price is product × size × channel × method, and NULL means ALL on every
   axis. The base row is emphasised and exceptions sit beneath it, because that
   is how an owner thinks: "this costs £X, except on delivery". */
.pl-filters{margin-top:14px;padding:12px;border:1px solid var(--nt-line);border-radius:13px;background:var(--nt-surface)}
.pl-filter-row{display:grid;grid-template-columns:92px minmax(0,1fr);gap:10px;align-items:start;padding:6px 0}
.pl-filter-label{padding-top:9px;font-size:12px;font-weight:800;color:var(--nt)}
.pl-chips{display:flex;flex-wrap:wrap;gap:7px}
.pl-chip{min-height:38px;padding:7px 14px;border:1px solid var(--np);border-radius:10px;background:var(--nt-surface);color:var(--np);font-family:inherit;font-size:12px;font-weight:600;line-height:1.2;cursor:pointer;white-space:nowrap}
.pl-chip:hover{background:var(--nt-surface-2)}
.pl-chip.on{background:var(--np);border-color:var(--np);color:#fff}
.pl-chip-count{display:inline-block;margin-left:6px;padding:1px 5px;border-radius:9px;background:color-mix(in srgb,currentColor 13%,transparent);font-size:10px}
.pl-tools{display:flex;align-items:center;gap:12px;margin:12px 0 7px}
.pl-search{flex:1 1 480px;max-width:680px}
.pl-legend{margin-left:auto;font-size:11.5px;color:var(--nt-ink-2);white-space:nowrap}
.pl-summary{margin:7px 0;font-size:12px;font-weight:700;color:var(--nt-ink-2)}
.pl-results-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:7px 0}
.pl-results-head .pl-summary{margin:0}
.pl-pagination{display:flex;align-items:center;justify-content:flex-end;gap:5px;margin:10px 0}
.pl-results-head .pl-pagination{margin:0}
.pl-page-button{min-width:34px;min-height:34px;padding:5px 9px;border:1px solid var(--nt-line);border-radius:8px;background:var(--nt-surface);color:var(--nt);font-family:inherit;font-size:11.5px;font-weight:700;cursor:pointer}
.pl-page-button:hover:not(:disabled){border-color:var(--np);color:var(--np);background:var(--nt-surface-2)}
.pl-page-button.on{border-color:var(--np);background:var(--np);color:#fff}
.pl-page-button:disabled{cursor:not-allowed;opacity:.45}
.pl-page-gap{min-width:16px;text-align:center;color:var(--nt-ink-2)}
.pl-message{margin:9px 0;padding:10px 12px;border-radius:9px;font-size:12.5px;font-weight:650}
.pl-message.good{background:color-mix(in oklab,var(--nt-paid) 12%,var(--nt-surface));color:var(--nt-paid-text)}
.pl-message.bad{background:color-mix(in oklab,var(--nt-failed) 10%,var(--nt-surface));color:var(--nt-failed-text)}
.pl-duplicate-banner{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin:14px 0 0;padding:11px 13px;border:1px solid var(--nt-waiting);border-radius:12px;background:color-mix(in oklab,var(--nt-waiting) 15%,var(--nt-surface));color:var(--nt-waiting-text)}
.pl-duplicate-text{flex:1 1 280px;min-width:0;font-size:12.5px;font-weight:800;line-height:1.45}
.pl-duplicate-note{display:block;font-size:11.5px;font-weight:600;opacity:.9}
.pl-duplicate-banner .n-btn{min-height:34px;flex:0 0 auto}
.pl-grid-scroll{position:relative;isolation:isolate;max-width:100%;overflow:auto;border:1px solid var(--nt-line);border-radius:12px;background:var(--nt-surface);overscroll-behavior-x:contain}
.pl-grid{width:100%;min-width:850px;border-collapse:separate;border-spacing:0;table-layout:fixed;font-size:12.5px}
.pl-grid th,.pl-grid td{height:52px;padding:7px 10px;border-right:1px solid var(--nt-line);border-bottom:1px solid var(--nt-line);vertical-align:middle;background:var(--nt-surface)}
.pl-grid th{height:42px;text-align:center;font-size:10.5px;text-transform:uppercase;letter-spacing:.035em;color:var(--nt-ink-2);background:var(--nt-surface-2)}
.pl-grid th small{display:block;text-transform:none;letter-spacing:0;font-size:9.5px;font-weight:500;margin-top:2px}
.pl-method-filter{display:block;box-sizing:border-box;width:100%;min-width:0;height:28px;margin-top:6px;padding:3px 20px 3px 6px;border:1px solid var(--nt-line);border-radius:7px;background:var(--nt-surface);color:var(--nt);font-family:inherit;font-size:10.5px;font-weight:650;letter-spacing:0;text-transform:none;cursor:pointer}
.pl-method-filter:focus{outline:2px solid color-mix(in srgb,var(--np) 25%,transparent);border-color:var(--np)}
.pl-grid thead{position:relative;z-index:5}
.pl-grid thead th{position:sticky;top:0;z-index:1;overflow:hidden}
.pl-grid tr:last-child td{border-bottom:0}
.pl-grid th:last-child,.pl-grid td:last-child{border-right:0}
.pl-grid .pl-product{position:sticky;left:0;z-index:2;width:250px;text-align:left;box-shadow:1px 0 0 var(--nt-line)}
.pl-grid th.pl-product{left:0;z-index:10;background:var(--nt-surface-2);background-clip:padding-box;transform:translateZ(0)}
.pl-product-cell{cursor:pointer;outline:none}
.pl-product-cell:hover,.pl-product-cell:focus{background:color-mix(in oklab,var(--nt-action) 9%,var(--nt-surface))}
.pl-product-cell:focus{box-shadow:inset 0 0 0 2px var(--np),1px 0 0 var(--nt-line)}
.pl-product-name{display:block;padding:4px 3px;color:var(--nt);font-size:13px;font-weight:700;line-height:1.35}
.pl-product-cell:hover .pl-product-name,.pl-product-cell:focus .pl-product-name{color:var(--np);text-decoration:underline}
.pl-override-count{display:block;width:max-content;max-width:calc(100% - 6px);margin:0 3px 3px;
 padding:2px 7px;border:1px solid var(--nt-waiting);border-radius:999px;background:color-mix(in oklab,var(--nt-waiting) 24%,var(--nt-surface));
 color:var(--nt-waiting-text);font-family:inherit;font-size:10px;font-weight:800;line-height:1.35;
 text-align:left}
.pl-delete-duplicates{display:block;width:max-content;max-width:calc(100% - 6px);min-height:28px!important;margin:5px 3px 3px;padding:4px 8px!important;font-size:10px!important}
.pl-price{display:block;width:100%;min-width:96px;height:40px;box-sizing:border-box;border:1px solid var(--nt-line);border-radius:8px;background:var(--nt-surface);color:var(--nt);font-family:inherit;font-size:16px;font-weight:700;line-height:1;text-align:right;padding:7px 9px}
.pl-price.inherited{font-weight:500;color:var(--nt-ink-2);background:var(--nt-surface-2)}
.pl-price.inherited::placeholder{color:var(--nt-ink-2);opacity:.85}
.pl-price:focus{outline:2px solid color-mix(in srgb,var(--np) 28%,transparent);border-color:var(--np)}
.pl-price.dirty{border-color:var(--np);background:color-mix(in oklab,var(--nt-action) 9%,var(--nt-surface));box-shadow:inset 0 0 0 1px var(--np)}
.pl-price.duplicate{color:var(--nt-failed-text);font-size:11px}
.pl-grid .pd-price-input{width:100%;min-width:82px;box-sizing:border-box;font-size:16px}
.pl-savebar{position:sticky;bottom:8px;z-index:20;display:flex;width:fit-content;align-items:center;gap:7px;margin:12px 0 0 auto;padding:7px 8px calc(7px + env(safe-area-inset-bottom));border:1px solid var(--nt-line);border-radius:11px;background:color-mix(in srgb,var(--nt-surface) 96%,transparent);box-shadow:0 6px 22px rgba(15,23,42,.13);backdrop-filter:blur(8px)}
.pl-save-status{font-size:12.5px;font-weight:700;color:var(--nt-ink-2)}
.pl-savebar .n-spacer{display:none}
.pl-savebar .n-btn{min-height:36px;padding:7px 13px}
@media (max-width:760px){
  .pl-filters{padding:8px;margin-top:10px}
  .pl-filter-row{grid-template-columns:78px minmax(0,1fr);gap:5px;padding:4px 0}
  .pl-filter-label{padding-top:12px}
  .pl-chips{flex-wrap:nowrap;overflow-x:auto;padding-bottom:3px;scrollbar-width:thin}
  .pl-chip{min-height:44px;padding:9px 14px}
  .pl-duplicate-banner{align-items:stretch;flex-direction:column;gap:7px}
  .pl-duplicate-banner .n-btn{min-height:44px;width:100%}
  .pl-tools{align-items:stretch;flex-direction:column;gap:6px}
  .pl-search{flex:auto;max-width:none;font-size:16px;min-height:44px}
  .pl-legend{margin-left:0;white-space:normal}
  .pl-results-head{align-items:flex-start;flex-direction:column;gap:6px}
  .pl-pagination{justify-content:flex-start;max-width:100%;overflow-x:auto;padding-bottom:2px}
  .pl-page-button{min-height:40px;white-space:nowrap}
  .pl-method-filter{height:40px;font-size:16px}
  .pl-grid{min-width:680px}
  .pl-grid .pl-product{width:170px}
  .pl-grid th.pl-product{z-index:20;min-width:170px;max-width:170px}
  .pl-grid th,.pl-grid td{padding:6px}
  .pl-product-name{font-size:12px}
  .pl-savebar{bottom:68px;margin-right:2px;max-width:calc(100vw - 24px);flex-wrap:nowrap}
  .pl-save-status{font-size:11.5px;white-space:nowrap}
  .pl-savebar .n-btn{flex:0 0 auto;min-height:40px;padding:8px 11px}
}

/* facts an owner can read but not edit — created date, owner, licence counts */
/* Debug tags (Nihat, 2026-09-06): the Supabase table.column behind a label, and the
   tables behind a Billing History tab. Amber so they never pass for the product's own copy. */
.st-dbg{display:inline-block;margin-left:6px;padding:1px 5px;border-radius:4px;background:color-mix(in oklab, var(--nt-waiting) 18%, var(--nt-surface));
 color:var(--nt-waiting-text);font:600 9.5px/1.5 ui-monospace,Consolas,monospace;letter-spacing:0;text-transform:none;
 vertical-align:middle;white-space:nowrap}
.st-dbg-bar{display:flex;align-items:flex-start;gap:8px;margin:-4px 0 12px}
.st-dbg-switch{appearance:none;font:inherit;font-size:11px;font-weight:700;cursor:pointer;white-space:nowrap;
 padding:4px 10px;border-radius:20px;border:1px solid var(--nt-waiting);background:color-mix(in oklab, var(--nt-waiting) 10%, var(--nt-surface));color:var(--nt-waiting-text)}
.st-dbg-switch.on{background:color-mix(in oklab,var(--nt-waiting) 70%,var(--nt-waiting-ink));border-color:var(--nt-waiting-text);color:#fff}
.st-dbg-row th{padding:0 8px 6px;border-bottom:1px solid var(--nt-line);background:transparent}
.st-dbg-line{flex:1;min-width:0;padding:6px 9px;border-radius:8px;background:color-mix(in oklab, var(--nt-waiting) 10%, var(--nt-surface));color:var(--nt-waiting-text);
 font:10.5px/1.5 ui-monospace,Consolas,monospace;overflow-wrap:anywhere}
.st-fact{display:flex;justify-content:space-between;align-items:baseline;
 gap:12px;padding:8px 0;border-bottom:1px solid var(--nt-line)}
.st-fact:last-child{border-bottom:none}
.st-factv{font-size:13px;font-weight:600;color:var(--nt)}

/* ── Menu structure ────────────────────────────────────────────────────────
   Groups left, products right. Below 760px they are two SCREENS, not two
   columns — a group list beside a product grid does not fit a thumb. */
.ms-menubar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.ms-wrap{display:grid;grid-template-columns:250px 1fr;gap:14px;align-items:start}
.ms-groups,.ms-products{background:var(--nt-surface);border:1px solid var(--nb);
 border-radius:14px;padding:14px}
.ms-g{display:flex;align-items:center;gap:6px;border-radius:9px;padding:2px 4px}
.ms-g.on{background:var(--np-fill)}
.ms-g.off{opacity:.5}
.ms-gname{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:8px;
 border:none;background:none;padding:9px 6px;cursor:pointer;font-family:inherit;
 text-align:left;font-size:13px;font-weight:700;color:var(--nt)}
.ms-gn{margin-left:auto;font-size:11px;font-weight:700;color:var(--nm);
 white-space:nowrap}
.ms-g.on .ms-gname,.ms-g.on .ms-gn{color:#fff}
.ms-gacts{display:flex;gap:2px;flex:0 0 auto}
.ms-gacts .n-btn{padding:4px 7px;min-height:0}
/* The bulk action sits under the ＋ on its own line: the panel is 250px and a
   fifth control in that header row would wrap into an unreadable stack. */
.ms-gbulk{display:block;width:100%;margin:8px 0 4px;text-align:center;
 line-height:1.25;white-space:normal}
.ms-product-head{flex-wrap:wrap}
.ms-product-title{display:flex;align-items:center;gap:7px;min-width:0}
.ms-colour-button{box-shadow:inset 0 0 0 1px color-mix(in oklab,#fff 24%,transparent)}

.ms-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;
 margin-top:10px}
/* The card is short — a name and its direct actions — so four fit a
   desktop comfortably and a fish-and-chip shop with 18 items in a group sees
   them without scrolling. Step down rather than squash. */
@media (max-width:1500px){.ms-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:1150px){.ms-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:760px){.ms-grid{grid-template-columns:1fr}}
.ms-card{border:1px solid var(--nb);border-radius:12px;padding:12px}
.ms-card.has-colour{color:var(--ms-card-ink);box-shadow:inset 0 0 0 1px rgba(255,255,255,.2)}
.ms-card.has-colour .ms-cname,.ms-card.has-colour .ms-cprice,
.ms-card.has-colour .n-sub{color:var(--ms-card-ink)}
.ms-card.has-colour .n-sub{opacity:.86}
.ms-card.n-clickable-row:hover{border-color:var(--np);box-shadow:0 2px 8px #0000000d}
.ms-card.n-clickable-row:focus-visible{outline-offset:2px}
.ms-ctop{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.ms-cname{font-size:13.5px;font-weight:700;color:var(--nt)}
.ms-cprice{font-size:13px;font-weight:700;color:var(--nt);white-space:nowrap}
.ms-cfoot{display:flex;align-items:center;gap:6px;margin-top:10px}
.ms-warn{font-size:11.5px;color:var(--nt-ink-2);background:var(--nt-surface);border-radius:8px;
 padding:6px 9px;margin-top:8px}
.ms-colour-editor{margin:0}
.ms-colour-preview{display:flex;align-items:center;justify-content:center;min-height:54px;
 margin:12px 0;border:1px solid var(--nt-line);border-radius:10px;font-size:13px;
 font-weight:800;box-shadow:inset 0 0 0 1px color-mix(in oklab,#fff 22%,transparent)}
.ms-colour-preview.is-default{background:var(--nt-surface-2);color:var(--nt);border-style:dashed;
 box-shadow:none}
.ms-colour-palette{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.ms-colour-swatch{display:flex;align-items:center;justify-content:center;width:36px;height:36px;
 padding:0;border:1px solid color-mix(in oklab,var(--nt-ink) 28%,transparent);
 border-radius:9px;font:900 16px/1 inherit;cursor:pointer}
.ms-colour-swatch:hover{transform:translateY(-1px)}
.ms-colour-swatch.on{outline:3px solid color-mix(in oklab,var(--nt-action) 25%,transparent);
 border-color:var(--np)}
.ms-pick{max-height:58vh;overflow-y:auto;border:1px solid var(--nb);
 border-radius:12px;margin-top:9px;background:var(--nt-surface)}
.ms-pick-cat+.ms-pick-cat{border-top:1px solid var(--nt-line)}
.ms-pick-cathead{display:flex;align-items:stretch;min-width:0}
.ms-pick-toggle{flex:1 1 auto;min-width:0;border:0;background:transparent;
 color:var(--nt);display:flex;align-items:center;gap:9px;padding:13px 12px;
 text-align:left;font:inherit;cursor:pointer}
.ms-pick-toggle:hover{background:var(--nt-surface-2)}
.ms-pick-chevron{width:17px;flex:0 0 17px;color:var(--nm);font-size:19px;
 line-height:1;text-align:center}
.ms-pick-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ms-pick-catcount{color:var(--nm);font-size:11.5px;white-space:nowrap}
.ms-pick-all{display:flex;align-items:center;gap:7px;padding:0 13px;
 border-left:1px solid var(--nt-line);font-size:12px;font-weight:700;
 color:var(--nt);white-space:nowrap;cursor:pointer}
.ms-pick-all.on{color:var(--np)}
.ms-pick-all:has(input:disabled){opacity:.45;cursor:default}
.ms-pick-items{border-top:1px solid var(--nt-line);background:var(--nt-surface-2)}
.ms-pick-product{display:flex;align-items:flex-start;gap:10px;
 min-height:44px;padding:10px 14px 10px 38px;border-bottom:1px solid var(--nt-line);
 cursor:pointer}
.ms-pick-product:last-child{border-bottom:0}
.ms-pick-product:hover{background:var(--nt-surface)}
.ms-pick-product.off{opacity:.58;cursor:default}
.ms-pick-productcopy{display:flex;flex-direction:column;gap:2px;min-width:0}
.ms-pick-productcopy .nm{font-size:13px;font-weight:700;color:var(--nt)}
.ms-pick-productcopy .ct{font-size:11.5px;color:var(--nm)}
.ms-pick-empty{padding:18px;text-align:center}

@media (max-width:760px){
  /* two screens: whichever the owner is on fills the width */
  .ms-wrap{grid-template-columns:1fr}
  .ms-wrap.narrow.view-groups .ms-products{display:none}
  .ms-wrap.narrow.view-products .ms-groups{display:none}
  .ms-grid{grid-template-columns:1fr}
  .ms-pick{max-height:62vh}
  .ms-pick-cathead{flex-wrap:wrap}
  .ms-pick-toggle{flex-basis:100%}
  .ms-pick-all{border-left:0;border-top:1px solid var(--nt-line);
   width:100%;min-height:44px;padding-left:38px}
  .ms-pick-product{padding-left:24px}
  .ms-product-title{flex:1 1 100%;flex-wrap:wrap}
  .ms-product-head>.n-spacer{display:none}
}

/* ── Modifier groups + the shared mapping grid ─────────────────────────────
   The dialog is four tabs; the mapping grid inside it can be eight columns
   wide, so it scrolls inside ITS OWN box rather than pushing the page. */
/* inside a side panel the dialog no longer sets its own width —
   the panel does, and the grid scrolls within it */
.mg-body{min-width:0;width:100%}
.mg-pane{margin-top:12px}
.mg-create-body{min-width:0}
.mg-details{display:flex;flex-direction:column;gap:12px;max-width:780px}
.mg-lead,.mg-tab-lead{border:1px solid color-mix(in oklab,var(--nt-action) 25%,var(--nt-line));
 border-radius:10px;padding:11px 13px;background:color-mix(in oklab,var(--nt-action) 5%,var(--nt-surface))}
.mg-field{display:flex;flex-direction:column;gap:6px;min-width:0}
.mg-label{color:var(--nt);font-size:11.5px;font-weight:800}
.mg-help{display:block;color:var(--nm);font-size:11px;line-height:1.4}
.mg-limit-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px}
.mg-appearance,.mg-behaviour{margin:0}
.mg-colour-row{display:flex;align-items:flex-start;gap:10px;margin-top:11px}
.mg-colour-preview{display:flex;align-items:center;justify-content:center;flex:0 0 190px;
 min-height:48px;border:1px solid color-mix(in oklab,var(--nt-ink) 28%,var(--nt-line));
 border-radius:9px;padding:9px 12px;font:800 12px/1.2 inherit;cursor:pointer;
 box-shadow:inset 0 0 0 1px color-mix(in oklab,#fff 22%,transparent)}
.mg-colour-preview.is-default{background:var(--nt-surface);color:var(--nt)!important;
 border-style:dashed;box-shadow:none}
.mg-colour-palette{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.mg-colour-palette[hidden]{display:none}
.mg-colour-swatch{display:flex;align-items:center;justify-content:center;width:32px;height:32px;
 padding:0;border:1px solid color-mix(in oklab,var(--nt-ink) 28%,transparent);
 border-radius:8px;color:#fff;font:900 16px/1 inherit;cursor:pointer}
.mg-colour-swatch:hover{transform:translateY(-1px)}
.mg-colour-swatch.on{outline:3px solid color-mix(in oklab,var(--nt-action) 25%,transparent);
 border-color:var(--np)}
.mg-option-list{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:11px}
.mg-option{display:flex;align-items:center;justify-content:space-between;gap:9px;min-width:0;
 min-height:72px;padding:10px;border:1px solid var(--nb);border-radius:9px;
 background:var(--nt-surface);color:var(--nt);font-family:inherit;text-align:left;cursor:pointer}
.mg-option:hover{background:var(--ns)}
.mg-option.on{border-color:var(--np);background:color-mix(in oklab,var(--nt-action) 7%,var(--nt-surface))}
.mg-option-copy{display:flex;flex-direction:column;gap:3px;min-width:0}
.mg-option-title{font-size:12px;font-weight:800}
.mg-option-state{flex:0 0 auto;border-radius:999px;padding:4px 7px;background:var(--nt-bg);
 color:var(--nm);font-size:9.5px;font-weight:900;text-transform:uppercase;letter-spacing:.035em}
.mg-option.on .mg-option-state{background:var(--np-fill);color:#fff}
.mg-message{min-height:18px;margin:0}
.mg-tab-lead{margin-bottom:12px}
.mg-two{display:grid;grid-template-columns:minmax(250px,.72fr) minmax(560px,1.8fr);
 gap:14px;align-items:start}
.mg-cat,.mg-sel{min-width:0;border:1px solid var(--nb);border-radius:12px;padding:12px;
 background:var(--nt-surface)}
.mg-section-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;
 margin-bottom:10px}
.mg-section-head>.n-sub{margin:0;white-space:nowrap}
.mg-select-all{display:flex;align-items:center;gap:8px;padding:9px 3px 0;color:var(--nt);
 font-size:12px;font-weight:700;cursor:pointer}
.mg-select-all input{width:16px;height:16px;accent-color:var(--np)}
.mg-cat .n-people{max-height:42vh}
.mg-add-bar{margin-top:10px;flex-wrap:wrap}
.mg-add-bar .n-btn{width:100%}
.mg-selected-head{align-items:center}
.mg-member-actions{flex-wrap:wrap;justify-content:flex-end}
.mg-selected-search{margin-top:10px}
.mg-rows{max-height:46vh;overflow-y:auto}
.mg-row{display:grid;grid-template-columns:minmax(180px,1fr) 112px 128px 92px;
 gap:8px;align-items:center;padding:9px 6px;border-bottom:1px solid var(--nt-line)}
.mg-row:last-child{border-bottom:none}
.mg-row.off{opacity:.5}
.mg-nm{min-width:0}
.mg-row-head{padding-top:11px;padding-bottom:7px;color:var(--nm);font-size:9.5px;
 font-weight:800;text-transform:uppercase;letter-spacing:.035em}
.mg-value{position:relative;display:block;min-width:0}
.mg-price .mg-num{padding-left:20px}
.mg-currency{position:absolute;left:8px;top:50%;z-index:1;transform:translateY(-50%);
 color:var(--nm);font-size:12px}
.mg-included{justify-content:flex-start;white-space:nowrap}
.mg-num{box-sizing:border-box;width:100%;border:1px solid var(--nb);border-radius:8px;padding:7px 8px;
 font-size:12.5px;font-family:inherit;color:var(--nt);text-align:right}
.mg-num:focus{outline:none;border-color:var(--np)}
.mg-prefix-lead{display:flex;align-items:center;justify-content:space-between;gap:12px}
.mg-prefix-count{margin:0 0 8px;color:var(--nm);font-size:11.5px;font-weight:700}
.mg-prefix-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px}
.mg-prefix-row{display:flex;align-items:center;justify-content:space-between;gap:12px;
 min-height:62px;border:1px solid var(--nb);border-radius:10px;padding:10px 12px;
 background:var(--nt-surface)}
.mg-prefix-row.on{border-color:color-mix(in oklab,var(--nt-action) 55%,var(--nt-line));
 background:color-mix(in oklab,var(--nt-action) 5%,var(--nt-surface))}
.mg-prefix-copy{min-width:0}
.mg-prefix-copy .nm{font-weight:800;color:var(--nt);font-size:13px}
.mg-prefix-copy .ct{margin-top:3px;color:var(--nm);font-size:11px}
.mg-prefix-switch{flex:0 0 auto;white-space:nowrap}

.mp-scroll{overflow-x:auto;max-width:100%;margin-top:10px;
 border:1px solid var(--nb);border-radius:12px}
.mp-grid{display:grid;min-width:640px;align-items:center}
/* One rule = one element, but on a desktop it must not become a grid item —
   `contents` dissolves the wrapper so its cells sit directly in the grid and
   the columns line up across rules exactly as they did before it existed. On a
   phone the wrapper reappears as the card (see the ≤760px block below). */
.mp-row{display:contents}
.mp-th{font-size:11px;font-weight:700;color:var(--nm);text-transform:uppercase;
 letter-spacing:.04em;padding:9px 8px;border-bottom:1px solid var(--nb);
 white-space:nowrap}
.mp-td{padding:6px 8px;border-bottom:1px solid var(--nt-line);min-width:0}
.mp-sel{margin-left:0;max-width:100%;width:100%}
/* an id whose option has gone away must LOOK wrong, not silently read "All" */
.mp-ghost{border-color:var(--nd);color:var(--nd)}
.mp-acts{display:flex;gap:4px;justify-content:flex-end}
.mp-none{padding:16px 10px;font-size:12.5px;color:var(--nm);text-align:center}
.mp-bar{gap:8px;margin-top:10px;flex-wrap:wrap}

@media (max-width:980px){
  .mg-two{grid-template-columns:1fr}
  .mg-cat .n-people{max-height:260px}
}
@media (max-width:760px){
  .mg-limit-grid,.mg-option-list,.mg-prefix-list{grid-template-columns:1fr}
  .mg-colour-row{display:block}
  .mg-colour-preview{width:100%;margin-bottom:10px}
  .mg-selected-head,.mg-prefix-lead{align-items:stretch;flex-direction:column}
  .mg-member-actions{justify-content:stretch}
  .mg-member-actions .n-btn{flex:1 1 auto}
  .mg-row-head{display:none}
  .mg-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:9px 10px;
   margin-top:9px;padding:11px;border:1px solid var(--nt-line);border-radius:10px}
  .mg-row:last-child{border-bottom:1px solid var(--nt-line)}
  .mg-nm{grid-column:1 / -1}
  .mg-row [data-l]::before{content:attr(data-l);display:block;margin-bottom:4px;
   color:var(--nm);font-size:9.5px;font-weight:800;text-transform:uppercase;
   letter-spacing:.035em}
  .mg-included{display:block}
  .mg-included input{vertical-align:middle;margin-right:5px}
  .mg-row>.n-btn{align-self:end;min-height:40px}
}

/* ---- Mappings stay a grid and scroll -------------------------------------
   A mapping is one rule read left-to-right. Turning its columns into a tall
   card makes two rules hard to compare and can put ten selects into one card.
   On phones the complete grid therefore keeps its headings and scrolls inside
   its own boundary. The page itself never becomes wider than the viewport. */
@media (max-width:760px){
  .mp-scroll{max-width:100%;overflow-x:auto;border:1px solid var(--nb);
   border-radius:12px;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
   scrollbar-width:thin;touch-action:pan-x pan-y}
  .mp-grid{display:grid;min-width:640px;width:max-content}
  .mp-row{display:contents}
  .mp-th{display:block;position:sticky;top:0;z-index:2;background:var(--ns)}
  .mp-td{display:block;padding:7px 8px;border-bottom:1px solid var(--nt-line)}
  .mp-td::before{content:none}
  .mp-sel,.mp-td .mg-num{width:100%;min-width:120px;max-width:none}
  .mp-split{border-left:2px solid var(--nb);border-top:none}
  .mp-acts{display:flex;justify-content:flex-end;min-width:76px}
}

/* ── Products ──────────────────────────────────────────────────────────────
   The pricing block is a small grid, not a table: three columns, and an
   inherited row has to LOOK inherited or an owner creates overrides by
   accident. */
.pd-body{min-width:0;width:100%}
.pd-pane{margin-top:12px}
.pd-details-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
 gap:12px;align-items:start;margin-bottom:12px}
.pd-detail-cell,.pd-menu-field{min-width:0}
.pd-detail-cell .kit-msg:empty,.pd-description .kit-msg:empty{display:none}
.pd-menu-box{min-height:72px;border:1px solid var(--nb);border-radius:10px;
 background:var(--nt-surface);padding:10px 12px}
.pd-menu-box>.n-sub:first-child{margin-top:0}
.pd-menu-box>.n-btn{margin-top:7px}

/* Category and menu groups, picked as chips.
   The chips sit in `display:contents` so they share the box's flex line with
   the input; the input itself is never re-parented, because rebuilding it on
   a keystroke drops focus and the field then takes one character and dies. */
.pd-picker{position:relative}
.pd-tokbox{display:flex;flex-wrap:wrap;gap:6px;align-items:center;
 border:1px solid var(--nb);background:var(--nt-surface);border-radius:8px;
 padding:7px 8px;min-height:44px;cursor:text}
.pd-tokbox:focus-within{border-color:var(--np);
 box-shadow:0 0 0 3px color-mix(in oklab,var(--np) 18%,transparent)}
.pd-toks{display:contents}
/* `pd-tok`, not `pd-chip`: the tag toggles further down already own that name,
   and two rules under one name are decided by which is later in the file
   rather than by which element they are on. */
.pd-tok{display:inline-flex;align-items:center;gap:6px;border-radius:999px;
 padding:4px 6px 4px 10px;font-size:12.5px;font-weight:700;white-space:nowrap;
 background:var(--ns);color:var(--nt)}
.pd-tok.cat{background:color-mix(in oklab,var(--nt-info-text) 14%,transparent);
 color:var(--nt-info-text)}
.pd-tok.menu{background:color-mix(in oklab,var(--nt-menu-text) 14%,transparent);
 color:var(--nt-menu-text)}
.pd-tok.tag{background:color-mix(in oklab,var(--nt-agent-text) 14%,transparent);
 color:var(--nt-agent-text)}
.pd-tok.off{background:var(--ns);color:var(--nm)}
.pd-tok-note{font-weight:600;font-size:11px;opacity:.85}
.pd-tok-x{border:0;background:none;cursor:pointer;font:inherit;font-size:13px;
 line-height:1;padding:0 3px;border-radius:999px;color:inherit;opacity:.65}
.pd-tok-x:hover{opacity:1;background:color-mix(in oklab,var(--nt) 12%,transparent)}
.pd-tok-input{flex:1 1 140px;min-width:140px;border:0;outline:0;background:none;
 font:inherit;color:var(--nt);padding:5px 4px}
.pd-tok-input::placeholder{color:var(--nm)}

.pd-optlist{position:absolute;z-index:30;left:0;right:0;top:calc(100% + 5px);
 background:var(--nt-surface);border:1px solid var(--nb);border-radius:10px;
 box-shadow:var(--nt-sh-2,0 8px 24px rgba(0,0,0,.12));max-height:268px;
 overflow-y:auto;padding:5px}
.pd-optlist[hidden]{display:none}
.pd-opt{display:flex;align-items:center;gap:8px;width:100%;border:0;
 background:none;font:inherit;text-align:left;padding:9px 10px;border-radius:7px;
 cursor:pointer;color:var(--nt)}
.pd-opt:hover,.pd-opt.on{background:var(--ns)}
.pd-opt.dim{color:var(--nm)}
.pd-opt mark{background:none;color:inherit;font-weight:800}
.pd-opt-note{margin-left:auto;font-size:11.5px;color:var(--nm)}
.pd-opt.make{color:var(--nt-paid-text);font-weight:700}
.pd-opt.make:hover,.pd-opt.make.on{
 background:color-mix(in oklab,var(--nt-paid-text) 12%,transparent)}
.pd-opt-empty{padding:9px 10px;color:var(--nm);font-size:13px}
.pd-opt-sep{height:1px;background:var(--nb);margin:4px 6px}

.pd-menus{display:grid;gap:8px}
.pd-menu-row{border:1px solid var(--nb);border-radius:10px;background:var(--ns);
 padding:9px 10px;display:grid;gap:6px}
.pd-menu-head{display:flex;align-items:baseline;gap:8px}
.pd-menu-name{font-weight:700;font-size:13px}
.pd-menu-count{margin-left:auto;font-size:11.5px;color:var(--nm)}
.pd-menu-row .pd-tokbox{background:var(--nt-surface)}
.n-link{border:0;background:none;padding:0;font:inherit;cursor:pointer;
 color:var(--np);text-decoration:underline}
.pd-description{margin-bottom:12px}
.pd-description textarea{min-height:82px;resize:vertical}
.pd-product-flags{margin-bottom:12px;padding-bottom:12px}
.pd-flag-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.pd-flag-toggle{display:flex;align-items:center;justify-content:space-between;gap:8px;
 min-height:44px;padding:8px 10px;border:1px solid var(--nb);border-radius:9px;
 background:var(--nt-surface);color:var(--nt);font:700 12px/1.2 inherit;cursor:pointer}
.pd-flag-toggle:hover{background:var(--ns)}
.pd-flag-toggle.on{background:var(--np-fill);border-color:var(--np);color:#fff}
.pd-flag-state{flex:0 0 auto;border-radius:999px;padding:3px 7px;
 background:var(--nt-bg);color:var(--nm);font-size:10px;font-weight:800;
 text-transform:uppercase;letter-spacing:.035em}
.pd-flag-toggle.on .pd-flag-state{background:rgba(255,255,255,.2);color:#fff}
.pd-appearance>.n-sub{margin-top:-2px}
.pd-appearance-grid{display:grid;grid-template-columns:minmax(260px,1fr) minmax(260px,1fr);
 gap:12px;margin-top:12px}
.pd-appearance-field{min-width:0;border:1px solid var(--nt-line);border-radius:10px;
 background:var(--nt-bg);padding:12px}
.pd-picture-row{display:flex;align-items:center;gap:13px;min-height:108px}
.pd-picture-frame{display:flex;align-items:center;justify-content:center;flex:0 0 132px;
 width:132px;height:100px;padding:0;overflow:hidden;border:1px dashed var(--nt-line);
 border-radius:10px;background:var(--nt-surface);color:var(--nm);cursor:pointer}
.pd-picture-frame:hover{border-color:var(--np);background:color-mix(in oklab,var(--nt-action) 5%,var(--nt-surface))}
.pd-product-photo{display:block;width:100%;height:100%;object-fit:cover}
/* `display:block` above beats the browser's own [hidden] rule, so hiding the
   photo in JS did nothing and a stale URL showed a broken icon over the "No
   picture" slot. An author rule is needed to undo an author rule. */
.pd-product-photo[hidden]{display:none}
.pd-picture-empty{padding:10px;font-size:12px;font-weight:700;text-align:center}
.pd-picture-controls{display:flex;align-items:flex-start;gap:7px;flex-wrap:wrap;min-width:0}
.pd-picture-controls>.n-sub{flex:1 0 100%;margin:0}
.pd-picture-file{display:none}
.pd-colour-preview{display:flex;align-items:center;justify-content:center;width:100%;
 min-height:64px;border:1px solid color-mix(in oklab,var(--nt-ink) 28%,var(--nt-line));
 border-radius:10px;padding:10px 14px;font:800 13px/1.25 inherit;cursor:pointer;
 box-shadow:inset 0 0 0 1px color-mix(in oklab,#fff 22%,transparent)}
.pd-colour-preview:hover{filter:brightness(.98)}
.pd-colour-preview.is-default{background:var(--nt-surface);
 color:var(--nt)!important;border-style:dashed;box-shadow:none}
.pd-colour-palette{display:flex;align-items:center;gap:7px;flex-wrap:wrap;
 margin-top:10px;padding-top:10px;border-top:1px solid var(--nt-line)}
.pd-colour-palette[hidden]{display:none}
.pd-colour-swatch{display:flex;align-items:center;justify-content:center;width:32px;
 height:32px;padding:0;border:1px solid color-mix(in oklab,var(--nt-ink) 28%,transparent);
 border-radius:8px;color:#fff;font:900 16px/1 inherit;cursor:pointer}
.pd-colour-swatch:hover{transform:translateY(-1px)}
.pd-colour-swatch.on{outline:3px solid color-mix(in oklab,var(--nt-action) 25%,transparent);
 border-color:var(--np)}
.pd-prices{border:1px solid var(--nb);border-radius:10px;margin-top:9px}
.pd-prow{display:grid;grid-template-columns:1fr 110px 96px;gap:10px;
 align-items:center;padding:8px 11px;border-bottom:1px solid var(--nt-line);
 font-size:12.5px}
.pd-prow:last-child{border-bottom:none}
.pd-phead{font-size:11px;font-weight:700;color:var(--nm);text-transform:uppercase;
 letter-spacing:.04em}
/* the everywhere-price showing through — not a price set on this tab */
.pd-inherit{background:var(--ns)}
.pd-inherit .mg-num{color:var(--nm)}
.md-daybox:has(.pd-price-v2){width:min(1100px,100%)}
.pd-price-v2>.n-row{align-items:flex-start}
.pd-scope-row{margin-top:13px}
.pd-scope-label{font-size:10.5px;font-weight:800;color:var(--nm);
 text-transform:uppercase;letter-spacing:.045em;margin-bottom:6px}
.pd-scope-choices{display:flex;gap:7px;flex-wrap:wrap}
.pd-scope-chip{border:1px solid var(--nb);background:var(--nt-surface);
 color:var(--nt);border-radius:9px;padding:8px 13px;font:600 12px/1 inherit;
 cursor:pointer}
.pd-scope-chip.on{background:var(--np-fill);border-color:var(--np);color:#fff}
.pd-scope-note{margin:13px 0;padding:10px 12px;border-radius:8px;
 background:color-mix(in oklab,var(--nt-action) 10%,var(--nt-surface));color:var(--nt-action-text);font-size:12px}
.pd-duplicate-warning{display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin:0 0 13px;padding:11px 12px;border:1px solid color-mix(in oklab,var(--nt-failed-text) 45%,var(--nt-line));border-radius:9px;background:color-mix(in oklab,var(--nt-failed) 10%,var(--nt-surface));color:var(--nt-failed-text)}
.pd-duplicate-warning .n-sub{margin-top:3px;color:var(--nt-failed-text)}
.pd-duplicate-warning .n-btn{flex:0 0 auto;background:var(--nt-surface)}
.pd-matrix-scroll,.pd-overrides-scroll{overflow-x:auto}
.pd-matrix{width:100%;min-width:720px;border-collapse:separate;border-spacing:0;
 border:1px solid var(--nb);border-radius:10px;overflow:hidden}
.pd-matrix th,.pd-matrix td{padding:9px;border-bottom:1px solid var(--nt-line);
 text-align:right;white-space:nowrap}
.pd-matrix th:first-child,.pd-matrix td:first-child{text-align:left}
.pd-matrix th{background:var(--ns);font-size:10.5px;text-transform:uppercase;
 letter-spacing:.035em;color:var(--nm)}
.pd-matrix th small{display:block;text-transform:none;letter-spacing:0;
 font-size:9.5px;font-weight:500;margin-top:2px}
.pd-matrix tbody tr:last-child td{border-bottom:none}
.pd-size-name{display:block;font-weight:650;margin-bottom:5px}
.pd-size-select{display:block;width:100%;min-width:120px;min-height:36px;margin-bottom:5px;padding:6px 28px 6px 8px;border:1px solid var(--nt-line);border-radius:8px;background:var(--nt-surface);color:var(--nt);font-family:inherit;font-size:13px;font-weight:650;cursor:pointer}
.pd-size-select:focus{outline:2px solid color-mix(in srgb,var(--np) 25%,transparent);border-color:var(--np)}
.pd-matrix td:first-child .n-btn{min-height:28px;padding:4px 7px;font-size:10px}
.pd-price-input{width:82px;border:1px solid var(--nb);border-radius:8px;
 padding:8px 7px;text-align:right;font:inherit;color:var(--nm);background:var(--ns)}
.pd-price-input.default{background:color-mix(in oklab,var(--nt-action) 10%,var(--nt-surface));border:2px solid color-mix(in oklab,var(--nt-action) 62%,var(--nt-line));
 color:var(--nt-action-text);font-weight:800}
.pd-price-input.override{background:color-mix(in oklab,var(--nt-waiting) 18%,var(--nt-surface));border:2px solid var(--nt-waiting);
 color:var(--nt-waiting-text);font-weight:800}
.pd-price-input.inherited{background:var(--ns);color:var(--nm)}
.pd-price-input.pending{background:var(--nt-surface);color:var(--nt);
 border-style:dashed}
.pd-price-input:disabled{background:var(--ns);color:var(--nm);cursor:not-allowed;
 opacity:.72}
.pd-cell-note{display:block;color:var(--nt-waiting-text);font-size:9.5px;font-weight:800;
 margin-top:3px;text-align:right}
.pd-cell-note.duplicate{color:var(--nt-failed-text)}
.pd-add-row{background:color-mix(in oklab,var(--nt-action) 3%,transparent)}
.pd-price-help{font-size:11.5px;color:var(--nm);margin:10px 0}
.pd-price-actions{margin-top:8px}
.pd-overrides{border:1px solid var(--nt-waiting);border-radius:10px;overflow:hidden;
 margin-top:17px;background:color-mix(in oklab,var(--nt-waiting) 7%,var(--nt-surface))}
.pd-overrides-head{display:flex;align-items:center;padding:11px 13px;
 background:color-mix(in oklab,var(--nt-waiting) 24%,var(--nt-surface));color:var(--nt-waiting-text)}
.pd-overrides-head .n-sub{color:var(--nt-waiting-text)}
.pd-overrides-table{width:100%;min-width:790px;border-collapse:collapse}
.pd-overrides-table th,.pd-overrides-table td{padding:9px 11px;
 border-top:1px solid color-mix(in oklab,var(--nt-waiting) 48%,var(--nt-line));text-align:left;white-space:nowrap;font-size:11.5px}
.pd-overrides-table th{background:color-mix(in oklab,var(--nt-waiting) 24%,var(--nt-surface));color:var(--nt-waiting-text);font-size:10px;
 text-transform:uppercase;letter-spacing:.035em}
.pd-overrides-table tbody tr{background:color-mix(in oklab,var(--nt-waiting) 12%,var(--nt-surface))}
.pd-override-value{font-weight:800;color:var(--nt-waiting-text)}
.pd-override-actions{display:flex;gap:6px}
.pd-no-overrides{text-align:center!important;color:var(--nm);padding:16px!important}
.md-daybox:has(.pd-schedule){width:min(1050px,100%)}
.pd-schedule{display:flex;flex-direction:column;gap:12px}
.pd-sch-lead{border:1px solid color-mix(in oklab,var(--nt-action) 38%,var(--nt-line));border-radius:10px;padding:12px 14px;
 background:color-mix(in oklab,var(--nt-action) 10%,var(--nt-surface));color:var(--nt)}
.pd-sch-lead>.n-row{align-items:flex-start}
.pd-sch-lead>.n-sub{color:var(--nt-action-text);max-width:760px}
.pd-sch-location{display:inline-flex;align-items:center;border-radius:999px;
 padding:4px 9px;background:var(--nt-surface);color:var(--nt-action-text);border:1px solid color-mix(in oklab,var(--nt-action) 32%,var(--nt-line));
 font-size:10.5px;font-weight:800;white-space:nowrap}
.pd-sch-toolbar{display:flex;align-items:center;gap:10px}
.pd-sch-save-state{font-size:11.5px;color:var(--nm)}
.pd-sch-save-state.dirty{color:var(--nt-waiting-text);font-weight:700}
.pd-sch-list{display:flex;flex-direction:column;gap:12px}
.pd-sch-card{overflow:hidden;border:1px solid var(--nb);border-left:4px solid var(--nt-action);
 border-radius:12px;background:var(--nt-surface)}
.pd-sch-card.hide{border-left-color:var(--nt-failed)}
.pd-sch-card.direct{border-left-color:var(--nt-waiting)}
.pd-sch-card-head{display:flex;justify-content:space-between;align-items:flex-start;
 gap:12px;padding:12px 14px;background:color-mix(in oklab,var(--nt-action) 5%,var(--nt-bg));
 border-bottom:1px solid var(--nt-line)}
.pd-sch-card.hide .pd-sch-card-head{background:color-mix(in oklab,var(--nt-failed) 9%,var(--nt-surface))}
.pd-sch-card.direct .pd-sch-card-head{background:color-mix(in oklab,var(--nt-waiting) 10%,var(--nt-surface))}
.pd-sch-title{display:flex;align-items:center;gap:8px}
.pd-sch-number{font-size:13px;font-weight:800;color:var(--nt)}
.pd-sch-action-pill{display:inline-flex;border-radius:999px;padding:3px 7px;
 background:color-mix(in oklab,var(--nt-action) 12%,var(--nt-surface));color:var(--nt-action-text);font-size:9.5px;font-weight:900;
 letter-spacing:.035em}
.pd-sch-card.hide .pd-sch-action-pill{background:color-mix(in oklab,var(--nt-failed) 16%,var(--nt-surface));color:var(--nt-failed-text)}
.pd-sch-card.direct .pd-sch-action-pill{background:color-mix(in oklab,var(--nt-waiting) 30%,var(--nt-surface));color:var(--nt-waiting-text)}
.pd-sch-summary{margin-top:4px;color:var(--nm);font-size:10.5px;line-height:1.4}
.pd-sch-fields{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
 gap:10px;margin-top:9px}
.pd-sch-scope-fields{padding:13px 14px 2px;margin-top:0}
.pd-sch-field{display:flex;flex-direction:column;gap:5px;min-width:0}
.pd-sch-label{color:var(--nm);font-size:10px;font-weight:800;
 text-transform:uppercase;letter-spacing:.04em}
.pd-sch-control{width:100%;min-width:0;height:40px;border:1px solid var(--nb);
 border-radius:9px;padding:7px 10px;background:var(--nt-surface);color:var(--nt);
 font:600 12px/1.2 inherit}
.pd-sch-control:focus{outline:none;border-color:var(--np);
 box-shadow:0 0 0 3px color-mix(in oklab,var(--nt-action) 11%,transparent)}
.pd-sch-window-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
 gap:10px;padding:11px 14px 0}
.pd-sch-block{min-width:0;border:1px solid var(--nt-line);border-radius:10px;
 padding:10px;background:var(--nt-bg)}
.pd-sch-block-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.pd-sch-block-title{font-size:11px;font-weight:800;color:var(--nt)}
.pd-sch-optional{font-size:9.5px;font-weight:700;color:var(--nm)}
.pd-sch-block>.n-sub{font-size:10.5px;margin-top:2px}
.pd-sch-days-block,.pd-sch-action-block{padding:12px 14px 0}
.pd-sch-action-block{padding-bottom:14px}
.pd-sch-days,.pd-sch-actions{display:flex;gap:6px;flex-wrap:wrap;margin-top:7px}
.pd-sch-day,.pd-sch-action{min-height:34px;border:1px solid var(--nb);
 border-radius:8px;padding:7px 11px;background:var(--nt-surface);color:var(--nt);
 font:700 11.5px/1 inherit;cursor:pointer}
.pd-sch-day:hover,.pd-sch-action:hover{background:var(--ns)}
.pd-sch-day.on,.pd-sch-action.show.on{background:var(--np-fill);
 border-color:var(--np);color:#fff}
.pd-sch-action.hide.on{background:var(--nt-failed-fill);border-color:var(--nt-failed-text);color:#fff}
.pd-sch-action.direct-link.on{background:color-mix(in oklab,var(--nt-waiting) 70%,var(--nt-waiting-ink));border-color:var(--nt-waiting-text);color:#fff}
.pd-sch-action-block>.n-sub{margin-top:7px;font-size:10.5px}
.pd-sch-empty{text-align:center;border:1px dashed var(--nb);border-radius:12px;
 padding:30px 18px;background:var(--nt-bg)}
.pd-sch-empty-icon{font-size:27px;color:var(--np);margin-bottom:5px}
.pd-sch-error{border:1px solid color-mix(in oklab,var(--nt-failed) 40%,var(--nt-line));border-radius:9px;padding:10px 12px;
 background:color-mix(in oklab,var(--nt-failed) 10%,var(--nt-surface));color:var(--nt-failed-text);font-size:12px;font-weight:650}
.pd-sch-error .n-sub{color:var(--nt-failed-text)}
.pd-chip{border:1px solid var(--nb);background:var(--nt-surface);border-radius:999px;
 padding:5px 12px;font-size:12px;font-weight:600;color:var(--nm);
 cursor:pointer;font-family:inherit}
.pd-chip:hover{background:var(--ns)}
.pd-chip.on{background:var(--nt-surface);border-color:var(--nt-line);color:var(--nt-ink)}

@media (max-width:800px){
  .pd-details-grid{grid-template-columns:1fr}
  .pd-appearance-grid{grid-template-columns:1fr}
  .pd-picture-row{align-items:flex-start}
  .pd-sch-window-grid{grid-template-columns:1fr}
}
@media (max-width:640px){
  .pd-flag-row{grid-template-columns:1fr}
  .pd-prow{grid-template-columns:1fr 88px 72px;gap:6px;padding:8px 7px}
  .pd-size-select{min-height:40px;font-size:16px}
  .pd-sch-fields{grid-template-columns:1fr}
  .pd-sch-toolbar{align-items:flex-start;flex-wrap:wrap}
  .pd-sch-toolbar .n-spacer{display:none}
  .pd-sch-save-state{flex:1 0 100%}
  .pd-sch-card-head{align-items:flex-start}
  .pd-sch-day{flex:1 0 calc(25% - 6px)}
}

/* ── the pricing grid: sizes down, order methods across (NET-705) ──────────
   Five columns do not fit a phone, so below 640px each size becomes a CARD and
   the order methods stack inside it, each box labelled — the heading row is the
   only thing that carried those names, and it is gone at that width (NET-318).
   The grid scrolls inside its own container on the way there; the dialog itself
   must never scroll sideways. */
.pg-scroll{overflow-x:auto;margin-top:9px;-webkit-overflow-scrolling:touch}
.pg-grid{border:1px solid var(--nb);border-radius:10px;min-width:520px}
.pg-row{display:grid;grid-template-columns:1.2fr repeat(var(--pg-cols,5),minmax(76px,1fr));
 gap:8px;align-items:center;padding:8px 11px;
 border-bottom:1px solid var(--nt-line);font-size:12.5px}
.pg-row:last-child{border-bottom:none}
.pg-head{font-size:11px;font-weight:700;color:var(--nm);text-transform:uppercase;
 letter-spacing:.04em}
.pg-head .pg-cell{align-items:flex-end;gap:1px}
/* "Default" and "all order methods" are the same thing said two ways, so the
   long one rides under the short one rather than replacing it. */
.pg-sub{font-size:9.5px;font-weight:600;letter-spacing:.02em;text-transform:none;
 color:var(--nt-ink-3);white-space:nowrap}
.pg-size{min-width:0;overflow-wrap:anywhere;font-weight:600}
.pg-cell{display:flex;flex-direction:column;gap:3px;min-width:0}
.pg-cell .mg-num{width:100%;min-width:0;text-align:right}
/* grey is not that cell's own price — it is what would be charged, showing
   through from a wider setting. An owner who cannot tell the two apart creates
   overrides by accident, which is the whole reason this is marked at all. */
.pg-inherit .mg-num{color:var(--nm);background:var(--ns)}
.pg-ex{font-size:10.5px;font-weight:700;color:var(--nt-brand-orange);
 letter-spacing:.02em;text-align:right}

@media (max-width:640px){
  .pg-scroll{overflow-x:visible}
  .pg-grid{min-width:0;border:none}
  .pg-head{display:none}
  .pg-sub{display:none}
  .pg-row{grid-template-columns:1fr;gap:7px;padding:11px;
   border:1px solid var(--nb);border-radius:10px;margin-bottom:9px}
  .pg-row:last-child{border-bottom:1px solid var(--nb)}
  .pg-size{font-size:13.5px}
  /* the label the heading row used to carry, now beside each box */
  .pg-cell{flex-direction:row;align-items:center;gap:8px}
  .pg-cell::before{content:attr(data-label);flex:1 1 auto;color:var(--nm);
   font-size:12px}
  .pg-cell .mg-num{flex:0 0 96px;width:96px}
  .pg-ex{flex:0 0 auto}
}

/* the boundary between "where it applies" and "what happens there" */
.mp-split{border-left:2px solid var(--nb)}

/* four across leaves the card narrow: let the footer wrap and keep the name
   from being crushed by the button row */
.ms-cfoot{flex-wrap:wrap;row-gap:6px}
.ms-cname{overflow-wrap:anywhere}

/* Products toolbar — search stays small, the actions sit beside it */
.pd-tools{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0}
.pd-search{max-width:260px;flex:0 1 260px}
.pd-cats{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.pd-cats .pd-chip{display:inline-flex;align-items:center;gap:6px}
.pd-chipn{font-size:11px;font-weight:700;opacity:.6}
@media (max-width:560px){.pd-search{max-width:none;flex:1 1 100%}}

/* ═══════════════════════════════════════════════════════════════════════════
   THE APP: offline state, update prompt
   ═══════════════════════════════════════════════════════════════════════════ */

/* "Nothing here yet" had no styling at all — kit.empty() has always built these
   three elements and they rendered as bare unstyled text, which reads like a
   half-loaded page rather than a deliberate message. Same shape as the offline
   state below, because they are the same kind of message. */
.kit-empty{text-align:center;padding:34px 20px}
.kit-empty-i{font-size:28px;line-height:1;margin-bottom:6px}
.kit-empty-t{font-weight:800;font-size:14.5px;color:var(--nt-ink);margin-bottom:3px}
.kit-empty .n-sub{max-width:340px;margin:0 auto}

/* Row actions. Three or four buttons at a thumb-friendly 44px do not fit
   beside a label on a 390px screen, so let them take their own line. */
@media (max-width:760px){
  .n-table td.kit-acts{flex-wrap:wrap;justify-content:flex-end;gap:6px;
   border-top:1px solid var(--nt-line);padding-top:9px}
  .n-table td.kit-acts::before{content:none}
}

/* Being offline is not an error and must not be styled like one. */
.kit-offline{text-align:center;padding:38px 20px;display:flex;
 flex-direction:column;align-items:center;gap:8px}
.kit-offline-i{font-size:30px;line-height:1}
.kit-offline-t{font-weight:800;font-size:15px;color:var(--nt-ink)}
.kit-offline .n-sub{max-width:340px}
.kit-offline .n-btn{margin-top:8px}

/* "Update ready" — a pill, not a dialog. It must never take the screen away
   from someone mid-edit; that is the whole reason the new version is waiting
   instead of installing itself. Above the phone's bottom nav bar. */
.sw-pill{position:fixed;left:50%;transform:translateX(-50%);
 bottom:calc(18px + env(safe-area-inset-bottom));z-index:120;
 border:0;border-radius:999px;padding:11px 18px;cursor:pointer;
 font:inherit;font-size:13px;font-weight:700;color:#fff;background:var(--nt-ground);
 box-shadow:0 10px 28px rgba(0,0,0,.28);animation:sw-rise .24s ease-out}
.sw-pill:disabled{opacity:.6;cursor:default}
@keyframes sw-rise{from{transform:translate(-50%,14px);opacity:0}
                   to{transform:translate(-50%,0);opacity:1}}
@media (max-width:760px){.sw-pill{bottom:calc(74px + env(safe-area-inset-bottom))}}

/* ── Opening Hours, laid out the way Google Business does it ────────────────
   Nihat, 2026-08-05: "opening hours design is wrong … you must do same as
   google business hours page."

   What was wrong was not taste. Every opening was a stack of five FULL-WIDTH
   dropdowns — day, from, to, channel, method — repeated per opening, so a
   normal week was 35 controls tall and the word "Monday" appeared five times.
   The classes it used (`cf-hr`, `cf-day`, `cf-t`) were never styled at all,
   which is why everything rendered at 100% width in a column.

   Google's shape: every day listed ONCE, in order, times side by side, a
   Closed tick, and a + to add a second period for a split shift. One line per
   day is the whole point — the week has to be readable at a glance, because
   the question an owner actually asks this page is "are my hours right?", not
   "what openings exist?". */
.hz-tabs{display:flex;gap:6px;flex-wrap:wrap;margin:2px 0 14px}
.hz-tab{border:1px solid var(--nb);background:var(--nt-surface);border-radius:999px;
 padding:7px 14px;cursor:pointer;font:inherit;font-size:13px;font-weight:600;
 color:var(--nt-ink);white-space:nowrap}
.hz-tab:hover{background:var(--nt-surface)}
.hz-tab.on{background:var(--nt-ground);border-color:var(--nt-line);color:#fff}
/* A day a method tab inherits from All (NET-954). Still editable — the first
   touch gives the method its own copy — but drawn so the owner can see which
   days are theirs and which are All's. */
.hz-hint{margin:-6px 0 12px}
.hz-inherit input[type=time],.hz-inherit select{border-style:dashed;
  color:var(--nt-ink-2)}
.hz-day{display:grid;grid-template-columns:120px 104px 1fr auto;
 align-items:start;gap:12px;padding:12px 0;border-top:1px solid var(--nb)}
.hz-day:first-of-type{border-top:0}
.hz-name{font-weight:700;padding-top:9px}
.hz-closed{display:flex;align-items:center;gap:7px;padding-top:10px;
 font-size:13px;color:var(--nt-ink-2);cursor:pointer;user-select:none}
.hz-closed input{width:16px;height:16px;cursor:pointer;accent-color:var(--nt-ink)}
.hz-periods{display:flex;flex-direction:column;gap:8px;min-width:0}
.hz-p{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.hz-p input[type=time]{width:112px;padding:8px 10px;border:1px solid var(--nb);
 border-radius:10px;font:inherit;background:var(--nt-surface)}
.hz-to{color:var(--nt-ink-2);font-size:13px}
.hz-ch{padding:8px 10px;border:1px solid var(--nb);border-radius:10px;
 font:inherit;font-size:13px;background:var(--nt-surface);color:var(--nt-ink-2);max-width:170px}
.hz-x,.hz-add{border:1px solid var(--nb);background:var(--nt-surface);border-radius:10px;
 width:34px;height:34px;line-height:1;cursor:pointer;font:inherit;
 font-size:16px;color:var(--nt-ink-2);flex:none}
.hz-x:hover{background:color-mix(in oklab, var(--nt-failed) 12%, var(--nt-surface));border-color:var(--nt-line);color:var(--nt-failed-text)}
.hz-add:hover{background:var(--nt-surface);color:var(--nt-ink)}
.hz-shut{color:var(--nt-ink-2);font-size:13px;padding-top:10px}
/* The save bar sticks, because the week is long and the button must not be a
   thing you scroll to find. */
.hz-bar{position:sticky;bottom:0;display:flex;align-items:center;gap:12px;
 padding:14px 0 4px;margin-top:6px;background:linear-gradient(to top,
 var(--nbg,var(--nt-surface)) 72%,rgba(247,248,250,0));z-index:5}
@media (max-width:760px){
  .hz-day{grid-template-columns:1fr;gap:6px;padding:14px 0}
  .hz-name{padding-top:0}
  .hz-closed{padding-top:0}
  .hz-ch{max-width:none;width:100%}
}

/* ── The sidebar is the apps you bought ─────────────────────────────────────
   Nihat, 2026-08-05. An accordion per app; the pages under it are that app's
   own entities. Locked apps stay on the list — a greyed row is a product an
   owner can ask for, a hidden one is a product they never learn we sell. */
.app-head{display:flex;align-items:center;gap:9px;padding:9px 10px;
 border-radius:10px;cursor:pointer;font-size:14px;font-weight:600;color:var(--nt-ink)}
.app-head:hover{background:var(--nt-surface)}
.app-head.locked{color:var(--nt-ink-2);cursor:pointer}
.app-ico{font-size:15px;line-height:1}
.app-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
 white-space:nowrap}
.app-caret{color:var(--nt-ink-2);font-size:11px}
.app-lock{font-size:11px;opacity:.75}
.app-kids{padding:2px 0 6px 12px;margin-left:12px;border-left:2px solid var(--nt-line)}
.app-kid{font-size:13.5px}
.app-note{padding:7px 10px;font-size:12.5px;color:var(--nt-ink-2);line-height:1.45}

/* ── the segmented rate control (NET-305) ───────────────────────────────────
 *
 * v1's ToggleTextWidget: one rounded container, two tappable halves, the
 * selected one raised and bordered and the other flat and muted. It replaces a
 * checkbox labelled "A fixed amount rather than a percentage", which asked the
 * reader to hold a negation in their head to work out what unticked meant.
 *
 * 44px is the row height v1 uses and the minimum comfortable touch target —
 * this is going into a phone wrapper, so the halves are sized for a thumb
 * rather than a cursor.
 */
/* A checkbox and its label are one control, so they sit on one line and the
 * whole row is the hit target. 44px is the touch height the segmented control
 * already uses; this goes into a phone wrapper too. */
.kit-check {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px; cursor: pointer;
  font-size: 14px; color: var(--nt);
}
.kit-check input[type=checkbox] { width: 20px; height: 20px; flex: none; }
.kit-check-hint { margin: -4px 0 10px 30px; }

/* A group heading inside a form. Sixteen controls in one column is a wall; the
 * same sixteen under Booking · Tracking · Ordering · Printing is a page you can
 * find something in. Sits above the first label of its group, so it needs the
 * space a label does not. */
.kit-head {
  font-size: 13px;
  font-weight: 800;
  color: var(--nt);
  margin: 18px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--nb);
}
.kit-form > .kit-head:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* The Advanced group on Location › Settings. Native <details>, so it opens with
 * no JavaScript and a keyboard reaches it the way the browser already knows. */
.st-adv { margin-top: 18px; border-top: 1px solid var(--nb); padding-top: 14px; }
.st-adv > summary {
  cursor: pointer; font-size: 13px; font-weight: 800; color: var(--nt);
  list-style: revert;
}
.st-adv[open] > summary { margin-bottom: 10px; }

/* NET-727 — the billing status card, and the owner sign-in that gates billing
 * actions inside the POS embed (KTD8). */
.st-status .n-btn { margin-top: 8px; }
.st-lic-msg:empty { display: none; }
.st-elev {
  position: fixed; inset: 0; z-index: 200; padding: 16px;
  background: rgba(0,0,0,.45);
  display: flex; align-items: center; justify-content: center;
}
.st-elev-box {
  width: 100%; max-width: 340px;
  display: flex; flex-direction: column; gap: 8px;
}

/* The permission matrix. Four columns of radios is narrow enough to read on a
 * phone but not to squeeze, so the TABLE scrolls rather than the page. */
.st-perm-scroll { overflow-x: auto; margin: 10px 0; }
.st-perm-scroll .n-table { min-width: 380px; }
.st-perm-scroll td, .st-perm-scroll th { vertical-align: top; }
.st-perm-scroll td input[type=radio] { width: 20px; height: 20px; margin: 2px 0; }

/* The banner grid, four across as v1 has it, each image with its own remove. */
.st-banners {
  display: grid; gap: 10px; margin: 10px 0 4px;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.st-banner { position: relative; aspect-ratio: 3 / 2; }
.st-banner img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: 10px; border: 1px solid var(--nb); display: block;
}
.st-banner button {
  position: absolute; top: 6px; right: 6px;
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--nb); background: var(--nt-surface); color: var(--nt);
  cursor: pointer; font-size: 14px; line-height: 1;
}
.st-banner button:hover { background: var(--ns); }

.kit-seg {
  display: flex;
  height: 44px;
  border-radius: 10px;
  background: var(--ns);
  padding: 3px;
  gap: 3px;
}
.kit-seg-b {
  flex: 1 1 0;
  min-width: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--nm);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
  padding: 0 8px;
}
.kit-seg-b.on {
  background: #fff;
  border-color: var(--nb);
  color: var(--nt);
  font-weight: 600;
}
/* Keyboard users get the same affordance as pointer users — the halves are
 * real buttons in tab order, so the focus ring has to be visible on them. */
.kit-seg-b:focus-visible {
  outline: 2px solid var(--np);
  outline-offset: -1px;
}

/* A right-aligned cell. `kit.table()` has emitted this class since it was
 * written and nothing ever styled it, so Products' price column has been
 * left-aligned all along — the rate columns would have been too. */
.n-table td.kit-r { text-align: right; }

/* ── the sort surface (NET-307) ─────────────────────────────────────────────
 *
 * Move buttons rather than drag: this goes into a phone wrapper where a drag
 * fights the scroll container, and buttons are the only version that is
 * keyboard-operable without implementing a drag protocol twice.
 */
.sort-list { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.sort-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 4px 8px;
  border: 1px solid var(--nb);
  border-radius: 8px;
  background: #fff;
}
.sort-n {
  min-width: 26px;
  text-align: right;
  color: var(--nm);
  font-variant-numeric: tabular-nums;
}
/* The name takes the slack so the two buttons stay put down the list — a
 * column of move buttons that shifts with each name length is unusable. */
.sort-name { flex: 1 1 auto; min-width: 0; overflow: hidden;
             text-overflow: ellipsis; white-space: nowrap; }

/* A segmented control the server will overrule anyway (NET-309). Muted rather
 * than hidden: the owner still needs to see WHICH way it was forced. */
.kit-seg.locked { opacity: .72; }
.kit-seg.locked .kit-seg-b { cursor: not-allowed; }

/* ── The order station (NET-404) ──────────────────────────────────────────
 *
 * A new order has to be noticeable from across a room, on a tab nobody is
 * looking at, with the sound possibly blocked by the browser. So the visible
 * change is the primary channel and the sound is the bonus — not the reverse.
 *
 * Two seconds and then it settles. A permanent flash gets the tab closed,
 * which loses the whole feature. */
@keyframes or-arrived {
  0%, 100% { box-shadow: 0 0 0 0 rgba(40, 96, 246, 0); }
  12%      { box-shadow: 0 0 0 8px rgba(40, 96, 246, .28); }
  50%      { box-shadow: 0 0 0 3px rgba(40, 96, 246, .16); }
}
.or-arrived > .n-card { animation: or-arrived 2s ease-out 2; }

/* Arrival popup: a visual channel independent of the pulse and sound. */
.station-popup {
  position: fixed; top: 72px; right: 20px; z-index: 2200;
  width: min(380px, calc(100vw - 32px));
  padding: 16px; border: 2px solid var(--np); border-radius: 14px;
  background: var(--nt-surface); color: var(--nt); box-shadow: var(--nt-sh-3);
  opacity: 0; transform: translateY(-12px); transition: opacity .18s, transform .18s;
}
.station-popup.on { opacity: 1; transform: translateY(0); }
.station-popup-title { font-size: 17px; font-weight: 800; }
.station-popup-copy { margin: 4px 0 12px; color: var(--nm); line-height: 1.4; }
body.booking-page .station-popup { top: 16px; }

/* Bookings has two independent live regions: the station and Reserve itself.
   Reserve owns only #bk-body, so its redraw and scroll contract cannot erase
   the alert above it or create a nested full-page scroller. */
#p-bookings.page { padding: 0; overflow: hidden; }
#p-bookings.page.on { display: flex; flex-direction: column; }
#bk-station { flex: 0 0 auto; padding: 10px 8px 0; background: var(--nt-bg); }
/* Answering a waiting request, in the card that told you about it. Each button
   carries its label and, under it, what the guest is sent — staff must never
   email a customer without knowing they are about to, so the two are one
   control and never separated. */
.bk-answer { white-space: nowrap; }
.bk-answer .n-btn {
  display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 1px; line-height: 1.25; text-align: left; padding: 6px 10px;
  min-height: 44px; margin: 2px 4px 2px 0;
}
.bk-answer .bk-answer-label { font-weight: 650; }
.bk-answer .bk-answer-tells { font-size: 11px; opacity: .85; }
.bk-answer .n-btn.is-busy { opacity: .6; }
.bk-answer .n-btn:disabled { opacity: .5; cursor: default; }
@media (max-width: 700px) {
  .bk-answer .n-btn { width: 100%; margin-right: 0; }
}
#bk-body { flex: 1 1 auto; min-height: 0; overflow: hidden; }

@media (max-width: 760px) {
  .station-popup { top: 12px; right: 12px; width: calc(100vw - 24px); }
}

/* Reduced motion still gets the alert, just held rather than pulsed — the
 * preference is about movement, not about being told an order arrived. */
@media (prefers-reduced-motion: reduce) {
  .or-arrived > .n-card { animation: none; box-shadow: 0 0 0 4px rgba(40, 96, 246, .22); }
  .station-popup { transition: none; transform: none; }
}

/* Announced, never shown. Used for the arrival message: the heading already
 * carries the count for eyes, and repeating it visibly would be two of the
 * same sentence. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ── embed mode (NET-682) ───────────────────────────────────────────────────
   The console showing ONE page inside a host app — POS today, KDS next. Same
   HTML, same scripts, same pages; only the chrome is gone.

   Hidden, and each for its own reason rather than "it looks tidier":

     .side      the sidebar. Handing a till the whole console puts users, roles
                and wallet spending one tap from the order screen during
                service. What a till should OFFER is a different question from
                what this person is PERMITTED to do, and only the first is
                being answered here.
     .n-scope   the venue picker. The till pushes its own venue; an owner with
                two restaurants must not be able to switch the one in front of
                them.
     #side-signout
                sign out. The host app owns the session; signing out from
                inside a web view would leave the till signed in and the page
                dead, with nothing to say why. It lives in the sidebar footer
                since 2026-09-01, and stands in the top bar on a phone — hiding
                it by id covers both places.
     #wchip     the wallet chip navigates to Settings, which does not exist as
                a destination when only one page is mounted.

   This block is the WHOLE of embed mode's presentation. If a page ever needs
   to know it is embedded beyond `body.embed` in CSS, that is the signal the
   decision has been outgrown and it is a conversation, not a commit — eleven
   Owner-dashboard UI issues are already in flight behind this. */
body.embed .side,
body.embed .n-scope,
body.embed #wchip,
body.embed #side-signout { display: none; }

/* THE SIGN-IN GATE, and it has to be CSS rather than the script.
   `boot()` returns early when there is no session yet, before the line that
   hides the gate — so in embed mode the login form sat there at z-index 50,
   under the waiting overlay at 60. Covered is not hidden: it was focusable by
   keyboard, and the handover removes the overlay, which would have uncovered a
   login form on a till that is already signed in.
   Found by driving a real browser (NET-682); no offline check could see it,
   because the markup was always correct. */
body.embed #gate { display: none !important; }

/* The page fills the window: there is no sidebar to sit beside. */
body.embed .main { margin-left: 0; width: 100%; }

/* Bookings carries its own complete title, venue context, date navigation and
   operational controls.  Repeating the generic console title above it wastes
   a full touch row in POS and produced the stray lowercase "bookings" bar the
   device test caught.  The class is toggled by go(), so every other Dashboard
   page keeps the shared account/location header. */
body.booking-page .top { display: none; }

/* NET-914 — Master Dashboard. Purple marks estate-wide context; business
   states keep the shared success/waiting/failed tokens. */
.master-return{position:sticky;top:0;z-index:45;width:100%;border:0;border-bottom:1px solid
 color-mix(in srgb,var(--nt-agent) 30%,var(--nt-line));padding:10px 18px;
 background:color-mix(in srgb,var(--nt-agent) 10%,var(--nt-surface));
 color:var(--nt-agent-text);font:800 13px/1.2 inherit;text-align:left;cursor:pointer}
.master-return[hidden]{display:none}
.master-head{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;margin-bottom:14px}
.master-head h2{margin:0 0 4px}.master-range{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
 margin:0 0 14px;padding:8px 0;border-bottom:1px solid var(--nt-line)}
.master-range-button{border:1px solid var(--nt-line);border-radius:999px;padding:7px 11px;background:var(--nt-surface);
 color:var(--nt-ink-2);font:800 11px/1 inherit;cursor:pointer}.master-range-button.on{border-color:var(--nt-agent);
 background:color-mix(in srgb,var(--nt-agent) 13%,var(--nt-surface));color:var(--nt-agent-text)}
.master-custom{display:inline-flex;align-items:center;gap:6px}.master-custom[hidden]{display:none}
.master-range-name{font-size:12px;font-weight:750;color:var(--nt-agent-text)}
.master-tabs{display:flex;gap:4px;overflow-x:auto;border-bottom:1px solid var(--nt-line);margin-bottom:16px}
.master-tab{flex:0 0 auto;border:0;border-bottom:3px solid transparent;padding:10px 12px;
 background:none;color:var(--nt-ink-2);font:750 13px/1.2 inherit;cursor:pointer}
.master-tab.on{border-bottom-color:var(--nt-agent);color:var(--nt-agent-text)}
.master-loading{padding:34px;text-align:center}.master-error{color:var(--nt-failed-text)}
.master-filter{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:14px;
 padding:10px;border:1px solid var(--nt-line);border-radius:12px;background:var(--nt-surface)}
.master-filter>.n-search{min-width:220px}.master-chips{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.master-filter-label{font-size:10px;font-weight:800;text-transform:uppercase;color:var(--nt-ink-2)}
.master-unset-note{flex-basis:100%;font-size:11px;color:var(--nt-ink-2)}
.master-chip{border:1px solid var(--nt-line);border-radius:999px;padding:6px 9px;background:var(--nt-surface);
 color:var(--nt-ink);font:700 11px/1 inherit;cursor:pointer}.master-chip.on{border-color:var(--nt-agent);
 background:color-mix(in srgb,var(--nt-agent) 13%,var(--nt-surface));color:var(--nt-agent-text)}
.master-showing{margin-left:auto;color:var(--nt-ink-2);font-size:11.5px;font-weight:700}
.master-hero{padding:22px;border-radius:16px;background:linear-gradient(135deg,
 color-mix(in srgb,var(--nt-agent) 18%,var(--nt-surface)),var(--nt-surface));
 border:1px solid color-mix(in srgb,var(--nt-agent) 28%,var(--nt-line));margin-bottom:14px}
.master-hero>strong{display:block;font-size:34px;line-height:1.1;color:var(--nt-agent-text)}
.master-eyebrow{font-size:10px;font-weight:850;text-transform:uppercase;letter-spacing:.08em;color:var(--nt-agent-text)}
.master-hero-note{margin-top:5px;color:var(--nt-ink-2)}.master-hero-split{display:flex;gap:18px;flex-wrap:wrap;
 margin-top:16px;padding-top:12px;border-top:1px solid var(--nt-line);font-weight:750}
.master-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-bottom:14px}
.master-tile{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-height:94px;padding:14px;
 border:1px solid var(--nt-line);border-radius:12px;background:var(--nt-surface);color:var(--nt-ink);text-align:left}
button.master-tile{cursor:pointer;font-family:inherit}button.master-tile:hover{border-color:var(--nt-agent)}
.master-tile-k{font-size:10.5px;font-weight:800;text-transform:uppercase;color:var(--nt-ink-2)}
.master-tile strong{font-size:19px}.master-tile-note{font-size:11px;color:var(--nt-ink-2)}
.master-tile .master-tile-money{font-size:16px;color:var(--nt-ink-2)}
.master-tile-due{background:color-mix(in oklab, var(--nt-failed) 10%, var(--nt-surface));border-color:color-mix(in oklab, var(--nt-failed) 35%, var(--nt-line))}
.master-state-bar{display:flex;width:100%;height:5px;margin-top:auto;border-radius:99px;overflow:hidden;background:var(--nt-line)}
.master-state-bar i.active{background:var(--nt-success)}.master-state-bar i.inactive{background:var(--nt-failed)}
.master-state-bar i.unset{background:var(--nt-waiting)}
.master-summary{grid-template-columns:repeat(4,minmax(0,1fr))}.master-summary .master-tile{min-height:78px}
.master-section{margin-bottom:14px}.master-section h3,.master-list-title{margin:0 0 11px}
.master-risk{display:grid;grid-template-columns:52px 1fr;gap:12px;padding:10px 0;border-bottom:1px solid var(--nt-line)}
.master-risk:last-child{border-bottom:0}.master-risk>strong{font-size:22px;color:var(--nt-agent-text)}
.master-risk b{text-transform:capitalize}.master-risk p{margin:3px 0 0;color:var(--nt-ink-2);font-size:12px}
.master-risk-detail{display:block}.master-risk-detail>summary{display:grid;grid-template-columns:52px 1fr;gap:12px;
 cursor:pointer;list-style:none}.master-risk-detail>summary::-webkit-details-marker{display:none}
.master-risk-detail>summary>strong{font-size:22px;color:var(--nt-agent-text)}
.master-risk-records{margin:8px 0 2px 64px;padding-left:18px;color:var(--nt-ink-2);font-size:12px;line-height:1.7}
.master-chart-grid{display:grid;grid-template-columns:2fr 1fr;gap:12px}.master-bar-row{display:grid;
 grid-template-columns:minmax(90px,1fr) 3fr auto;align-items:center;gap:9px;padding:6px 0;font-size:11.5px}
.master-bar{height:8px;border-radius:99px;background:var(--nt-surface-2);overflow:hidden}.master-bar i{display:block;height:100%;
 border-radius:inherit;background:var(--nt-agent)}.master-reconcile,.master-explain,.master-warning{padding:12px 14px;
 border-radius:10px;background:var(--nt-surface-2);color:var(--nt-ink-2);font-size:12px;line-height:1.5;margin-top:12px}
.master-warning{background:color-mix(in srgb,var(--nt-waiting) 14%,var(--nt-surface));color:var(--nt-waiting-text)}
.master-population{margin:10px 0;padding:8px 11px;border-left:3px solid var(--nt-agent);background:var(--nt-surface-2);
 color:var(--nt-agent-text);font-size:11.5px;font-weight:750}
.master-table-card{padding:0;margin-bottom:16px}.master-table-scroll{overflow-x:auto}.master-table{min-width:760px}
.master-sort{border:0;background:none;color:inherit;font:inherit;font-weight:800;cursor:pointer;white-space:nowrap}
.master-sort-dir{color:var(--nt-agent-text)}.master-row-link{cursor:pointer}.master-row-link:hover{background:var(--nt-surface-2)}
.master-overdue{background:color-mix(in srgb,var(--nt-failed) 8%,var(--nt-surface))}.master-footer td{font-weight:800;
 border-top:2px solid var(--nt-line)}.master-create{border-color:var(--nt-agent)!important;background:var(--nt-agent)!important;color:#fff!important}
.master-list-title{font-size:15px;margin-top:18px}.master-estate-tools{display:flex;gap:7px;margin-bottom:10px}
.master-company{padding:0;margin-bottom:9px;overflow:hidden}.master-company.orphan{border-color:var(--nt-waiting)}
.master-company-head{display:grid;grid-template-columns:minmax(230px,2fr) repeat(6,auto) auto;align-items:center;gap:14px;padding:11px 13px}
.master-estate-date{color:var(--nt-ink-2);font-size:11.5px;white-space:nowrap}
.master-company-name,.master-location-name{border:0;background:none!important;color:var(--nt-agent-text)!important;
 font-weight:800;text-align:left;justify-self:start}.master-locations{border-top:1px solid var(--nt-line);background:var(--nt-surface-2)}
.master-location-row{display:grid;grid-template-columns:minmax(190px,1.5fr) auto auto minmax(90px,.7fr) minmax(180px,1.5fr)
 auto auto auto;align-items:center;gap:12px;padding:9px 16px 9px 32px;border-bottom:1px solid var(--nt-line);font-size:12px}
.master-location-row:last-child{border-bottom:0}.master-address{color:var(--nt-ink-2)}.master-toggle{min-width:76px}
.master-toggle.on{border-color:var(--nt-success);color:var(--nt-success-text)}
.master-drawer .md-daybox{width:min(680px,100%)}
/* A drawer reads as sections, not a wall of rows: an eyebrow before each group and a
   plain sentence where the old build printed table names at the master. */
.master-drawer-section{font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
 color:var(--nm);margin:18px 0 2px}
.master-drawer-section:first-child{margin-top:0}
.master-note{margin:0 0 12px;font-size:12.5px;line-height:1.55;color:var(--nt-ink-2)}
.master-cycle{display:inline-flex;gap:6px}
.master-cycle .chip{appearance:none;font:inherit;font-size:12.5px;cursor:pointer;
 padding:5px 13px;border-radius:20px;border:1px solid var(--nb);background:var(--nt-surface);
 color:var(--nt-ink-2)}
.master-cycle .chip:hover{background:var(--ns);color:var(--nt)}
.master-cycle .chip.on{background:var(--nt-agent);border-color:var(--nt-agent);color:#fff;font-weight:620}.master-field{display:flex;flex-direction:column;gap:5px;margin:11px 0;
 font-size:11px;font-weight:800;color:var(--nt-ink-2)}.master-field .n-sel{width:100%}
.master-order-line,.master-invoice-line{display:flex;align-items:center;gap:9px;padding:9px 0;border-bottom:1px solid var(--nt-line)}
.master-line-pick{display:grid;grid-template-columns:18px minmax(170px,1fr) 40px minmax(150px,190px) 92px 138px minmax(120px,170px);
 align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--nt-line)}
.master-line-head{display:grid;grid-template-columns:18px minmax(170px,1fr) 40px minmax(150px,190px) 92px 138px minmax(120px,170px);
 align-items:end;gap:10px;padding:0 0 6px;font-size:10px;font-weight:800;
 text-transform:uppercase;letter-spacing:.04em;color:var(--nt-ink-2)}
.master-line-head>span:nth-child(3){text-align:center}
.master-gift-cell{display:flex;align-items:center;gap:6px;justify-self:center}
.master-gift-cell>small{display:none;font-size:11px;font-weight:700;color:var(--nt-ink-2);cursor:pointer}
.master-line-head>span:nth-child(5){text-align:right}
.master-quote{font-size:11px;line-height:1.35;color:var(--nt-ink-2)}
.master-quote.warn{color:var(--nw)}
.master-quote.bad{color:var(--nd)}
.master-effect-empty{color:var(--nt-ink-2)}
.n-pill.idle{background:var(--nt-surface-2);color:var(--nt-ink-2)}
.master-sweep-rows{display:flex;flex-direction:column}
.master-sweep-row{display:flex;align-items:flex-start;gap:10px;padding:9px 0;border-bottom:1px solid var(--nt-line)}
.master-sweep-row.master-waiting{opacity:.72}
.master-sweep-total{font-size:12px;font-weight:700;color:var(--nt-ink-2)}
.n-sel{box-sizing:border-box;width:100%;border:1px solid var(--nb);border-radius:8px;
 padding:7px 9px;font-size:12.5px;font-family:inherit;color:var(--nt);
 background:var(--nt-surface);min-height:34px}
.n-sel:focus{outline:none;border-color:var(--np);
 box-shadow:0 0 0 3px color-mix(in oklab, var(--nt-action) 10%, transparent)}
.n-sel:disabled{color:var(--nm);background:var(--nt-line);cursor:not-allowed}
.master-amount{text-align:right}
.master-line-pick.master-new{background:color-mix(in oklab, var(--nt-action) 4%, transparent)}
.master-cycle{display:none}
.master-line-name{flex:1;display:flex;flex-direction:column;gap:2px}
.master-line-name>small{font-size:11px}
.master-licence-no{font-weight:400}
.master-invoice-line .master-line-name{flex:1}.master-invoice-line .master-amount{width:110px}.master-invoice-line.void{opacity:.6}
.master-live{color:var(--nt-agent-text)}
.master-more{color:var(--ng);font-weight:600}.master-less{color:var(--nd);font-weight:600}
.master-idle{color:var(--nt-ink-2)}
/* NET-979: a stopped subscription reads as history — muted, dated, never as money. */
.master-was{font-style:italic;white-space:nowrap}
.master-stopped{white-space:nowrap}
.master-stopped-since{font-size:11px;color:var(--nt-ink-2)}
.master-line-pick.master-idle,.master-line-pick.master-dormant{opacity:.72}
.master-line-pick.master-dormant{border-left:2px solid var(--nt-line);padding-left:8px}
.master-effect{display:grid;gap:4px;margin:8px 0 2px}
.master-effect p{margin:0;font-size:12px;color:var(--nt-ink-2)}
.master-effect-on{color:var(--nt-agent-text)}
.master-effect-warn{color:var(--nt-warn)}
.master-key{width:100%;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.02em}
.master-add-licence{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:12px 0 4px}
.master-free-row{display:flex;align-items:center;gap:12px;padding:8px 10px;border-bottom:1px solid var(--nt-line);border-radius:8px}
.master-free-row .master-line-name{flex:1}.master-free-row:last-child{border-bottom:0}
.master-free-name{font-weight:400;font-size:13px}
.master-free-row.off{background:color-mix(in oklab, var(--nd) 9%, var(--nt-surface));border-bottom-color:transparent}
.master-free-row.off .master-free-name{color:var(--nd)}
.master-add-licence>small{color:var(--nt-ink-2);font-size:11px;flex:1;min-width:180px}
.master-risk-fix{margin-left:10px;vertical-align:middle}
.master-risk-value{color:var(--nt-agent-text);font-size:12px}
.master-line-pick .n-sel{min-width:0}.master-compare{display:grid;grid-template-columns:1fr auto;
 gap:8px;margin:14px 0;padding:12px;border-radius:10px;background:var(--nt-surface-2)}

.master-next-invoice,.st-next-invoice{display:inline-flex;flex-direction:column;align-items:center;gap:1px;
 font-weight:400;line-height:1.25;padding:6px 12px;min-height:0;white-space:nowrap}
.master-two-line{display:inline-flex;flex-direction:column;gap:2px}
.master-notes{min-height:52px;resize:vertical;font:inherit}
.master-gift-cell .master-server{margin-left:6px}
.master-order-line{align-items:flex-end;flex-wrap:wrap}.master-line-field{display:flex;flex-direction:column;gap:4px;
 font-size:10.5px;font-weight:800;color:var(--nt-ink-2)}.master-line-field.master-line-item{flex:1 1 200px}
.master-line-field.master-line-item .n-sel{width:100%}.master-line-field input{width:96px}
.master-line-field .master-subtotal{background:var(--nt-surface-2);color:var(--nt);font-weight:700;text-align:right}
.master-order-line>.n-btn{margin-bottom:1px}.master-running-total{display:block;text-align:right;margin-top:12px;font-size:17px}
.master-history-line{padding:10px 0;border-bottom:1px solid var(--nt-line)}.master-history-line p{margin:4px 0 0;color:var(--nt-ink-2)}
@media(max-width:1000px){.master-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}.master-chart-grid{grid-template-columns:1fr}
 .master-company-head{grid-template-columns:minmax(190px,1fr) repeat(2,auto) auto}.master-company-head>:nth-child(2),.master-company-head>:nth-child(3),.master-company-head>:nth-child(5),.master-company-head>:nth-child(6){display:none}
 .master-location-row{grid-template-columns:minmax(150px,1fr) 100px auto auto}.master-location-row .master-address,.master-location-row>:nth-child(2),.master-location-row>:nth-child(3),.master-location-row>:nth-child(6){display:none}}
@media(max-width:760px){.master-head{flex-direction:column}.master-range{width:100%}.master-filter{align-items:stretch}
 .master-filter>.n-search{width:100%;min-width:0}.master-chips{flex-wrap:nowrap;overflow-x:auto}.master-showing{margin-left:0}
 .master-tiles,.master-summary{grid-template-columns:1fr 1fr}.master-hero>strong{font-size:28px}.master-company-head{grid-template-columns:1fr auto}
 .master-company-head>:not(:first-child):not(:last-child){display:none}.master-location-row{grid-template-columns:1fr auto;padding-left:15px}
 .master-location-row>:not(:first-child):not(:last-child){display:none}
 .master-line-head{display:none}
 .master-line-pick{grid-template-columns:18px 1fr;row-gap:7px}
 .master-line-pick>:nth-child(n+3){grid-column:2}
 .master-line-pick>.master-gift-cell{justify-self:start}.master-gift-cell>small{display:inline}}

/* Roomier than the browser default. A till is a touch screen at arm's length,
   not a mouse at 60cm. */
body.embed .n-btn,
body.embed .n-tab { min-height: 44px; }

#embed-wait { display: none; }
body.embed #embed-wait {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: var(--nt-surface); color: var(--nt-ink-2);
  font: 15px system-ui;
}
/* ═══ LOCATION DASHBOARD · OPERATIONS PULSE ════════════════════════════════
   The page scrolls inside `.page`, below the shared header. The period row
   reaches top:0 first; the group row reaches top:54px later, leaving both
   controls visible without pinning the large KPI/weather content. */
.ld-periods,.ld-groups{display:flex;gap:7px;overflow-x:auto;max-width:100%;
 overscroll-behavior-x:contain;scrollbar-width:thin;background:var(--nt-bg)}
.ld-periods{position:sticky;top:0;z-index:31;margin:10px 0 12px;padding:8px 0;
 border-bottom:1px solid var(--nt-line)}
.ld-period,.ld-group,.ld-weather-range{flex:0 0 auto;min-height:38px;padding:8px 13px;
 border:1px solid var(--nt-line);border-radius:9px;background:var(--nt-surface);
 color:var(--nt);font:700 12px/1.2 inherit;white-space:nowrap;cursor:pointer}
.ld-period:hover,.ld-group:hover,.ld-weather-range:hover{border-color:var(--np);color:var(--np)}
.ld-period.on,.ld-group.on{border-color:var(--np);background:var(--np);color:#fff}
.ld-kpis{display:grid;grid-template-columns:repeat(5,minmax(135px,1fr));gap:10px;
 margin-bottom:12px}
.ld-card{min-width:0;margin:0;padding:15px;border-color:var(--nt-line);
 background:var(--nt-surface);box-shadow:0 5px 18px rgba(23,25,37,.035)}
.ld-kpi{position:relative;min-height:112px;overflow:hidden}
.ld-kpi::after{content:"";position:absolute;right:-22px;bottom:-34px;width:78px;height:78px;
 border-radius:50%;background:color-mix(in srgb,var(--np) 7%,transparent)}
.ld-kpi-label{position:relative;z-index:1;color:var(--nt-ink-2);font-size:10.5px;
 font-weight:800;letter-spacing:.045em;text-transform:uppercase}
.ld-kpi-value{position:relative;z-index:1;margin:9px 0 5px;color:var(--nt);
 font-size:25px;font-weight:850;line-height:1.1;letter-spacing:-.035em}
.ld-kpi-note{position:relative;z-index:1;color:var(--nm);font-size:10.5px;line-height:1.35}
.ld-kpi.loading{opacity:.68}.ld-mini-grid{display:grid;grid-template-columns:repeat(5,minmax(125px,1fr));
 gap:10px;margin-bottom:12px}.ld-mini-grid .ld-kpi{min-height:98px}.ld-mini-grid .ld-kpi-value{font-size:21px}

.ld-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
 margin-bottom:12px}.ld-card-head h3{margin:0;color:var(--nt);font-size:14.5px;
 line-height:1.3}.ld-card-head .n-sub{margin-top:2px}
.ld-weather{margin-bottom:13px}.ld-weather .ld-card-head{align-items:center}
.ld-weather-ranges{display:flex;gap:3px;padding:3px;border-radius:9px;background:var(--nt-surface-2)}
.ld-weather-range{min-height:32px;padding:6px 9px;border-color:transparent;background:transparent;
 color:var(--nt-ink-2);font-size:10.5px}.ld-weather-range.on{background:var(--nt-surface);color:var(--np);
 box-shadow:0 1px 4px rgba(23,25,37,.11)}
.ld-weather>.ld-empty{min-height:96px;margin:0;background:var(--nt-surface-2)}
.ld-weather-days{display:grid;grid-template-columns:repeat(7,minmax(105px,1fr));gap:8px;
 overflow-x:auto;overscroll-behavior-x:contain;padding:2px 0 4px;scrollbar-width:thin}
.ld-weather-day{display:flex;min-width:105px;min-height:132px;flex-direction:column;
 align-items:center;padding:10px 7px;border:1px solid var(--nt-line);border-radius:10px;
 background:var(--nt-surface-2);text-align:center}
.ld-weather-day.today{border:2px solid var(--nt-waiting);background:color-mix(in oklab,var(--nt-waiting) 18%,var(--nt-surface));color:var(--nt-waiting-text);
 box-shadow:0 0 0 2px color-mix(in srgb,var(--nt-waiting) 10%,transparent)}
.ld-weather-day.today .ld-weather-date,.ld-weather-day.today .ld-weather-low,
.ld-weather-day.today .ld-weather-detail{color:var(--nt-waiting-text)}
.ld-weather-day.past{border-color:var(--nt-line);background:var(--nt-raised);color:var(--nm);
 opacity:.62}
.ld-weather-day.past .ld-weather-icon{filter:grayscale(1)}
.ld-weather-day.past>strong{color:var(--nm)}
.ld-weather-day>b{font-size:11.5px}.ld-weather-date,.ld-weather-low,.ld-weather-detail{
 color:var(--nm);font-size:9.5px;line-height:1.35}.ld-weather-icon{margin:7px 0 3px;
 font-size:25px;line-height:1}.ld-weather-day>strong{font-size:18px;line-height:1.15}
.ld-weather-low{margin-bottom:6px}.ld-skeleton-card{height:138px;min-height:138px}

.ld-groups{position:sticky;top:54px;z-index:30;margin:0;padding:8px 0 9px;
 border-bottom:1px solid var(--nt-line)}
.ld-group-body{min-height:360px;padding-top:10px}.ld-section-title{display:flex;align-items:center;
 justify-content:space-between;gap:12px;margin:0 1px 10px;color:var(--nt);font-size:18px;
 font-weight:850}.ld-section-title span{color:var(--nm);font-size:11px;font-weight:650}
.ld-two{display:grid;grid-template-columns:minmax(0,1.45fr) minmax(280px,.8fr);gap:12px;
 margin-bottom:12px}.ld-three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;
 margin-bottom:12px}.ld-four{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;
 margin-top:12px}.ld-stack{display:grid;gap:12px;align-content:start}

.ld-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;
 min-height:138px;padding:18px;text-align:center;border:1px dashed var(--nt-line);
 border-radius:10px;background:var(--nt-bg)}
.ld-empty-icon{display:grid;place-items:center;width:36px;height:36px;margin-bottom:7px;
 border-radius:11px;background:var(--nt-surface);color:var(--np);font-size:19px}
.ld-empty b{font-size:12.5px}.ld-empty p{max-width:500px;margin:4px 0 10px;color:var(--nm);
 font-size:11.5px;line-height:1.45}.ld-empty .n-btn{margin-top:3px}
.ld-loading-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px}
.ld-skeleton{height:170px;border:1px solid var(--nt-line);border-radius:13px;
 background:linear-gradient(100deg,var(--nt-surface-2) 25%,var(--nt-surface) 42%,
 var(--nt-surface-2) 59%);background-size:300% 100%;animation:ld-shimmer 1.35s infinite}
@keyframes ld-shimmer{0%{background-position:100% 0}100%{background-position:0 0}}

.ld-event,.ld-activity{display:grid;grid-template-columns:46px minmax(0,1fr);gap:10px;
 align-items:center;padding:10px 2px;border-bottom:1px solid var(--nt-line)}
.ld-event:last-child,.ld-activity:last-child{border-bottom:0}.ld-event-date{padding:5px 3px;
 border:1px solid color-mix(in srgb,var(--np) 35%,var(--nt-line));border-radius:9px;
 background:color-mix(in srgb,var(--np) 7%,var(--nt-surface));color:var(--np);
 text-align:center;text-transform:uppercase;font-size:9px;font-weight:800}
.ld-event-date b{display:block;font-size:16px;line-height:1}.ld-activity{grid-template-columns:34px minmax(0,1fr)}
.ld-activity-icon{display:grid;place-items:center;width:32px;height:32px;border-radius:9px;
 background:var(--nt-surface-2);font-size:16px}

.ld-breakdown{display:grid;gap:11px}.ld-breakdown-row>div:first-child{display:flex;
 align-items:center;justify-content:space-between;gap:10px}.ld-breakdown-row b{font-size:11.5px}
.ld-breakdown-row span{color:var(--nm);font-size:10.5px;text-align:right}.ld-bar{height:5px;
 margin-top:5px;overflow:hidden;border-radius:99px;background:var(--nt-surface-2)}
.ld-bar i{display:block;height:100%;border-radius:inherit;background:var(--np)}
.ld-bars{display:flex;align-items:flex-end;gap:8px;min-height:205px;padding:12px 5px 0;
 overflow-x:auto;overscroll-behavior-x:contain}.ld-bar-col{display:flex;flex:1 0 48px;
 flex-direction:column;align-items:center;justify-content:flex-end;min-width:48px;height:190px}
.ld-bar-col i{display:block;width:min(34px,72%);min-height:4px;border-radius:6px 6px 2px 2px;
 background:linear-gradient(180deg,color-mix(in srgb,var(--np) 72%,white),var(--np))}
.ld-bar-value{margin-bottom:5px;color:var(--nt);font-size:9.5px;font-weight:750;
 white-space:nowrap}.ld-bar-label{margin-top:6px;color:var(--nm);font-size:9.5px;white-space:nowrap}

.ld-table-wrap{max-width:100%;overflow:auto;overscroll-behavior-x:contain;
 border:1px solid var(--nt-line);border-radius:10px}.ld-table-wrap:focus-visible{outline:2px solid var(--np);
 outline-offset:2px}.ld-table{width:100%;min-width:580px;border-collapse:collapse;background:var(--nt-surface)}
.ld-table th{padding:8px 9px;border-bottom:1px solid var(--nt-line);background:var(--nt-surface-2);
 color:var(--nt-ink-2);font-size:9.5px;font-weight:800;letter-spacing:.04em;text-align:left;
 text-transform:uppercase;white-space:nowrap}.ld-table td{padding:10px 9px;border-bottom:1px solid var(--nt-line);
 color:var(--nt);font-size:11.5px}.ld-table tr:last-child td{border-bottom:0}
.ld-table th:first-child,.ld-table td:first-child{width:34px;color:var(--nm)}
.ld-table th:nth-last-child(-n+2),.ld-table td:nth-last-child(-n+2){text-align:right}
.ld-table th.ld-sort{cursor:pointer;user-select:none}.ld-table th.ld-sort:hover,
.ld-table th.ld-sort:focus-visible{color:var(--np);outline:none}.ld-table th.ld-sort::after{content:'↕';
 margin-left:4px;opacity:.45}.ld-table th[aria-sort=descending]::after{content:'↓';opacity:1}
.ld-table th[aria-sort=ascending]::after{content:'↑';opacity:1}.ld-table th[aria-sort]{color:var(--np)}
.ld-table-empty{text-align:center!important;padding:30px 14px!important;color:var(--nt)!important}
.ld-table-empty .n-sub{margin-top:5px}.ld-updated{display:flex;align-items:center;justify-content:flex-end;
 gap:8px;padding:11px 1px 4px;color:var(--nm);font-size:10.5px}
.ld-user-list{display:grid;gap:2px}.ld-user-metric{display:flex;align-items:center;
 justify-content:space-between;gap:10px;padding:9px 1px;border-bottom:1px solid var(--nt-line)}
.ld-user-metric:last-child{border-bottom:0}.ld-user-metric b{display:block;font-size:11.5px}
.ld-user-metric span{display:block;margin-top:2px;color:var(--nm);font-size:9.5px}
.ld-user-metric strong{font-size:12px;white-space:nowrap}

@media (max-width:1180px){
 .ld-kpis{grid-template-columns:repeat(5,minmax(145px,1fr));overflow-x:auto;
  padding-bottom:3px;scrollbar-width:thin}.ld-kpi{min-width:145px}
 .ld-mini-grid{grid-template-columns:repeat(3,minmax(145px,1fr))}
 .ld-four{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:900px){
 .ld-two{grid-template-columns:1fr}.ld-three{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
 .ld-periods{top:0;margin:5px -12px 10px;padding:7px 12px;scrollbar-width:none}
 .ld-periods::-webkit-scrollbar,.ld-groups::-webkit-scrollbar{display:none}
 .ld-period,.ld-group{min-height:44px;padding:10px 14px;font-size:12.5px}
 .ld-kpis{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));overflow:visible;gap:8px}
 .ld-kpi{min-width:0;min-height:105px;padding:13px}.ld-kpi:first-child{grid-column:1/-1}
 .ld-kpi-value{font-size:21px}.ld-kpi-label{font-size:9.5px}
 .ld-weather{padding:13px}.ld-weather .ld-card-head{display:block}
 .ld-weather-ranges{margin-top:10px;max-width:100%;overflow-x:auto}
 .ld-weather-range{min-height:40px;flex:1 0 auto;padding:8px 10px}
 .ld-weather-days{margin:0 -1px;grid-template-columns:repeat(7,105px);scroll-snap-type:x proximity}
 .ld-weather-day{scroll-snap-align:start}
 .ld-groups{top:58px;margin:0 -12px;padding:7px 12px 8px;scrollbar-width:none}
 .ld-group-body{padding-top:9px}.ld-section-title{font-size:16px}
 .ld-mini-grid{display:flex;margin:0 -12px 12px;padding:0 12px 3px;overflow-x:auto;
  scroll-snap-type:x proximity;scrollbar-width:thin}.ld-mini-grid .ld-kpi{flex:0 0 145px;
  scroll-snap-align:start}.ld-mini-grid .ld-kpi:first-child{grid-column:auto}
 .ld-two,.ld-three,.ld-four{grid-template-columns:1fr}
 .ld-card{padding:13px}.ld-bars{margin:0 -5px}.ld-table{min-width:560px}
 .ld-updated{justify-content:flex-start;flex-wrap:wrap;padding-bottom:10px}
}
@media (max-width:390px){
 .ld-kpis{grid-template-columns:1fr 1fr}.ld-kpi{padding:12px}.ld-kpi-value{font-size:19px}
 .ld-weather>.ld-empty{padding:13px}.ld-section-title span{display:none}
}
