/* SnapPOS Lite - the kitchen register.
 *
 * Built against an iPad in landscape: 1080x810 CSS px, holding from 1024x768
 * to 1194x834. Height is the budget that matters, so every fixed row above the
 * grid is counted here rather than discovered at 6am:
 *
 *   header 56 + menu row 48 (absent at one menu) + category bar 88 + search 48
 *   = 240, leaving ~570px of grid at 810.
 *
 * The Safari details are not decoration. touch-action on the tiles is the one
 * that would otherwise be diagnosed during a breakfast rush: without it, four
 * fast taps on Taco fire double-tap-to-zoom instead of adding four.
 */

:root {
  --bg: #f4f5f7;
  --panel: #ffffff;
  --ink: #14161a;
  --ink-soft: #5b6270;
  --line: #d9dce3;
  --accent: #0b7285;
  --accent-ink: #ffffff;
  --danger: #b02a37;
  --ok: #1c7c4a;
  --tile-bg: #ffffff;
  --on-ok: #ffffff;
  --tile-press: #eef1f4;
  --mini-press: #e3e6ec;
  --modifier-bg: #fbfcfd;
  --soldout-a: #eceef1;
  --soldout-b: #e2e5ea;
  --radius: 10px;
  --gap: 8px;
}

/* Dark. Three states, because "system" stamps nothing on the root element:
 * an explicit choice sets data-theme, and the media query covers the default.
 * Every token is defined on bare :root above and only REDEFINED here, so no
 * colour has its single definition inside a conditional block.
 *
 * Worth having on a till rather than being fashion: a truck serving a night
 * pitch and a doughnut shop opening at 5am in the dark are both staring at the
 * brightest object in the vehicle. The choice is per device, not per shop -
 * two iPads in different light want different answers.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #101317;
    --panel: #171b21;
    --ink: #eef1f5;
    --ink-soft: #9aa4b2;
    --line: #2b323b;
    --accent: #2596a8;
    --accent-ink: #06181c;
    --danger: #f0748a;
    --ok: #2f9d68;
    --on-ok: #06180e;
    --tile-bg: #1c2128;
    --tile-press: #252c35;
    --mini-press: #252c35;
    --modifier-bg: #141920;
    --soldout-a: #1a1f26;
    --soldout-b: #20262e;
  }
}

:root[data-theme="dark"] {
  --bg: #101317;
  --panel: #171b21;
  --ink: #eef1f5;
  --ink-soft: #9aa4b2;
  --line: #2b323b;
  --accent: #2596a8;
  --accent-ink: #06181c;
  --danger: #f0748a;
  --ok: #2f9d68;
  --on-ok: #06180e;
  --tile-bg: #1c2128;
  --tile-press: #252c35;
  --mini-press: #252c35;
  --modifier-bg: #141920;
  --soldout-a: #1a1f26;
  --soldout-b: #20262e;
}

/* Native controls - the file picker, the number spinners, the select arrow -
   are drawn by the browser and stay light unless told otherwise. */
:root[data-theme="dark"] { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }
/* The default, where no choice has been made and the media query above is what
   decides. Without this the browser assumes a light page and paints a white
   canvas between navigations - so a till following a dark device flashed white
   on the way to every screen, even once the attribute arrived in time. Saying
   the page handles both also lets native controls draw themselves correctly in
   the state nobody explicitly chose. */
:root { color-scheme: light dark; }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.3 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* No text selection anywhere on a till: a long press to 86 an item must not
     pop the copy/paste bubble over the tile it just acted on. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* dvh, not vh - Safari's chrome appearing must not shove the pay button off
   the bottom of a screen somebody is already reaching for. */
.kt-app {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  overflow: hidden;
}

/* ---------------------------------------------------------------- header */

.kt-header {
  flex: 0 0 auto;
  height: 56px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.kt-brand { font-weight: 700; letter-spacing: .02em; }
.kt-header .kt-spacer { flex: 1; }

.kt-header a,
.kt-linkbtn {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 15px;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  background: none;
  cursor: pointer;
}
.kt-header a:active, .kt-linkbtn:active { background: var(--bg); }

/* ------------------------------------------------------------ menu row */

/* Rendered only when there are two or more menus. A truck running one board
   gets this row's 48px back for tiles, from the same markup. */
.kt-menus {
  flex: 0 0 auto;
  display: flex;
  gap: var(--gap);
  padding: 6px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.kt-menus.kt-hidden { display: none; }

.kt-menu-btn {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 20px;
  font-size: 16px;
  font-weight: 600;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink-soft);
  touch-action: manipulation;
}
/* The selected board is the inverse of the page, in both themes. It read as
   white-on-white in dark while `color` was hardcoded - the selected menu was
   the one you could not see. */
.kt-menu-btn[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--bg);
}

/* -------------------------------------------------------- category bar */

/* Wraps. Deliberately never scrolls horizontally: a scrolling bar hides
   categories, which destroys the only property the bar exists for - drinks
   being one tap away from the dish you just added. Eleven categories at
   1024px is two rows of six, always visible. */
.kt-cats {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.kt-cat-btn {
  min-height: 40px;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid var(--line);
  border-left: 4px solid var(--cat, var(--line));
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--ink);
  touch-action: manipulation;
}
.kt-cat-btn[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  border-left-color: var(--cat, var(--accent));
  color: var(--accent-ink);
}

/* ------------------------------------------------------------ workspace */

.kt-work {
  flex: 1 1 auto;
  display: flex;
  min-height: 0;
}

/* 65/35, not 70/30. At 1080 wide, 30% is 324px and three touch controls eat
   132px of it before any text - "Country Ham Egg Biscuit" wraps into soup.
   35% gives 378px, which holds it. */
.kt-grid-pane {
  flex: 0 0 65%;
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 1px solid var(--line);
}

.kt-searchbar {
  flex: 0 0 auto;
  display: flex;
  gap: var(--gap);
  padding: 8px 12px;
}

.kt-searchbar input {
  flex: 1;
  min-height: 40px;
  padding: 0 12px;
  font-size: 16px;          /* 16px or iOS zooms the page on focus */
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--ink);
  -webkit-user-select: text;
  user-select: text;
}

.kt-grid {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  grid-auto-rows: 84px;
  gap: var(--gap);
  padding: 0 12px 12px;
  overflow-y: auto;
  /* Or dragging the tile pane rubber-bands the whole page behind it. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* Comfortable density: a truck running eight items should not be handed a
   wall of postage stamps. Same grid, different minimum. */
.kt-grid.kt-comfortable {
  grid-template-columns: repeat(auto-fill, minmax(164px, 1fr));
  grid-auto-rows: 116px;
}

/* Every tile is a name plate. There is no photo variant - see
   docs/kitchen-register-design.md, "No item photos". */
.kt-tile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 8px;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--tile-bg);
  border: 1px solid var(--line);
  border-top: 4px solid var(--cat, var(--accent));
  border-radius: var(--radius);
  /* THE one that would be diagnosed at 6am: without it, four fast taps on the
     same tile trigger double-tap-to-zoom instead of adding four. */
  touch-action: manipulation;
  overflow: hidden;
}
.kt-tile:active { background: var(--tile-press); }

/* Placeholder tiles shown until the menu loads (see register.html). They keep
   the register looking like itself on a cold open instead of flashing an empty
   grid behind the search box. Inert: no taps, no category stripe. */
.kt-tile.kt-skel {
  border-top-color: var(--line);
  background: var(--tile-bg);
  pointer-events: none;
  position: relative;
  overflow: hidden;
}
.kt-tile.kt-skel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, var(--line) 50%, transparent 80%);
  opacity: .6;
  transform: translateX(-100%);
  animation: kt-shimmer 1.2s ease-in-out infinite;
}
@keyframes kt-shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .kt-tile.kt-skel::after { animation: none; }
}

.kt-tile-name {
  font-weight: 600;
  font-size: 14px;
  line-height: 1.2;
  /* Two lines, then ellipsis. Biscuit names are long and a tile that grows to
     fit one breaks the row it is in. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.kt-tile-price { font-size: 13px; color: var(--ink-soft); }
.kt-tile-cat { font-size: 11px; color: var(--ink-soft); text-transform: uppercase; }

.kt-tile.kt-soldout {
  opacity: .45;
  background: repeating-linear-gradient(
    -45deg, var(--soldout-a), var(--soldout-a) 6px,
    var(--soldout-b) 6px, var(--soldout-b) 12px);
}
.kt-tile.kt-soldout .kt-tile-name::after {
  content: " · 86";
  color: var(--danger);
}

.kt-empty {
  grid-column: 1 / -1;
  padding: 32px 8px;
  text-align: center;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------- order pane */

.kt-order {
  flex: 0 0 35%;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--panel);
}

.kt-order-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  font-weight: 700;
}

.kt-lines {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px 8px;
}

.kt-line {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  padding: 6px 4px;
  border-bottom: 1px solid var(--line);
}
.kt-line.kt-modifier { padding-left: 18px; background: var(--modifier-bg); }

.kt-line-main { flex: 1; min-width: 0; }
.kt-line-name { font-size: 15px; font-weight: 600; }
.kt-line-note {
  font-size: 13px;
  color: var(--accent);
  font-style: italic;
}
.kt-line-price { font-size: 13px; color: var(--ink-soft); }

.kt-qty {
  display: flex;
  align-items: center;
  gap: 2px;
}
.kt-qty span { min-width: 22px; text-align: center; font-weight: 600; }

.kt-mini {
  min-width: 34px;
  min-height: 34px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--ink);
  touch-action: manipulation;
}
.kt-mini:active { background: var(--mini-press); }
.kt-mini.kt-x { color: var(--danger); }
/* The add-on button, in the accent - the same colour a paid chip uses, so
   everything that charges the customer reads the same way. Written as
   .kt-mini.kt-addon rather than .kt-addon because both are single classes on
   one element and source order would otherwise decide; see .kt-chip-paid,
   which had the same problem. */
.kt-mini.kt-addon {
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 800;
}

.kt-order-foot {
  flex: 0 0 auto;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--line);
}

.kt-total {
  display: flex;
  justify-content: space-between;
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 8px;
}

.kt-actions { display: flex; gap: var(--gap); }

.kt-btn {
  flex: 1;
  min-height: 52px;
  font-size: 17px;
  font-weight: 700;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink);
  touch-action: manipulation;
}
.kt-btn:active { background: var(--mini-press); }
.kt-btn.kt-pay {
  flex: 2;
  background: var(--ok);
  border-color: var(--ok);
  color: var(--on-ok);
}
.kt-btn:disabled { opacity: .4; }

/* --------------------------------------------------------------- modal */

.kt-modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(12, 14, 18, .45);
  padding: 16px;
  z-index: 20;
}
.kt-modal[hidden] { display: none; }

.kt-modal-card {
  width: min(560px, 100%);
  max-height: 90dvh;
  overflow-y: auto;
  background: var(--panel);
  border-radius: 14px;
  padding: 16px;
}
.kt-modal-card h2 { margin: 0 0 4px; font-size: 19px; }
.kt-modal-sub { margin: 0 0 12px; color: var(--ink-soft); font-size: 14px; }

.kt-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }

/* A PAID option reads differently from a note, because pressing it charges
   the customer. Outlined in the accent rather than filled: it is an action
   with a consequence sitting among toggles that have none, and a cashier
   should be able to tell them apart at a glance on a moving line. */
/* .kt-chip.kt-chip-paid, not .kt-chip-paid. The element carries both classes
   and both selectors weigh the same, so SOURCE ORDER would decide - and
   .kt-chip is defined below this, which would have quietly won every colour.
   Two classes beats one wherever either sits. */
.kt-chip.kt-chip-paid {
    border-color: var(--accent, #0b7285);
    color: var(--accent, #0b7285);
    font-weight: 600;
}
.kt-chip.kt-chip-paid[disabled] { opacity: 0.5; }

/* Tapped, not typed. Free text at a lunch rush produces "no onion",
   "No Onions" and "w/o onion" on three consecutive orders, none of which can
   be reported on and all of which are slow. */
.kt-chip {
  min-height: 40px;
  padding: 0 14px;
  font-size: 15px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--bg);
  color: var(--ink);
  touch-action: manipulation;
}
.kt-chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.kt-modal input[type="text"],
.kt-modal input[type="number"],
.kt-modal select {
  width: 100%;
  min-height: 44px;
  padding: 0 12px;
  font-size: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--ink);
  -webkit-user-select: text;
  user-select: text;
}

.kt-modal-actions { display: flex; gap: var(--gap); margin-top: 14px; }

/* --------------------------------------------------------------- toast */

.kt-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  max-width: 90vw;
  padding: 12px 18px;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--bg);
  font-size: 15px;
  z-index: 40;
}
.kt-toast[hidden] { display: none; }
.kt-toast.kt-bad { background: var(--danger); }

/* ---------------------------------------------------------- items admin */

.kt-admin { padding: 16px; overflow-y: auto; flex: 1; }
.kt-admin h2 { margin: 0 0 12px; font-size: 20px; }

.kt-admin-cols { display: flex; gap: 16px; align-items: flex-start; }
.kt-admin-side { flex: 0 0 300px; }
.kt-admin-main { flex: 1; min-width: 0; }

.kt-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 12px;
}
.kt-card h3 { margin: 0 0 8px; font-size: 16px; }

.kt-list { list-style: none; margin: 0; padding: 0; }
.kt-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
}
.kt-list li:last-child { border-bottom: 0; }
.kt-list .kt-grow { flex: 1; min-width: 0; }
.kt-list .kt-muted { color: var(--ink-soft); font-size: 13px; }

.kt-row { display: flex; gap: var(--gap); margin-bottom: 8px; }
.kt-row > * { flex: 1; }

.kt-admin input[type="text"],
.kt-admin input[type="number"],
.kt-admin select {
  width: 100%;
  min-height: 44px;
  padding: 0 10px;
  font-size: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--ink);
  -webkit-user-select: text;
  user-select: text;
}

.kt-admin .kt-btn { min-height: 44px; font-size: 15px; }
.kt-btn.kt-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

/* Portrait. An iPad gets rotated, and the answer is a real layout rather than
   a plea to turn it back: the order pane goes under the grid and the grid
   keeps its tiles. */
@media (orientation: portrait) {
  .kt-work { flex-direction: column; }
  .kt-grid-pane { flex: 1 1 auto; border-right: 0; border-bottom: 1px solid var(--line); }
  .kt-order { flex: 0 0 42%; }
  .kt-admin-cols { flex-direction: column; }
  .kt-admin-side { flex: 1 1 auto; width: 100%; }
}

/* The theme button. Sized like everything else a thumb reaches for, and
   deliberately not an icon-only mystery: it says which way it is going. */
.kt-theme {
  min-height: 40px;
  padding: 0 14px;
  font: inherit;
  font-size: 15px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--ink-soft);
  touch-action: manipulation;
}
.kt-theme:active { background: var(--mini-press); }

/* The attach banner. Loud on purpose - it changes what the next tap does, and
   a mode you cannot see is a mode that puts an extra on the wrong burger. */
.kt-attach {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 600;
  background: var(--accent);
  color: var(--accent-ink);
}
.kt-attach[hidden] { display: none; }
.kt-attach .kt-mini {
  background: var(--accent-ink);
  border-color: var(--accent-ink);
  color: var(--accent);
  min-width: auto;
  padding: 0 12px;
  font-size: 14px;
}

/* An inline display:flex beats the browser's own [hidden] { display: none },
   so a hidden row stays on screen - which is how a cash refund was offering to
   put the money back on a card. Class, not inline style, and the hidden rule
   wins explicitly. */
.kt-check {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
  font-size: 15px;
}
.kt-check[hidden] { display: none; }
.kt-check input[type="checkbox"] { width: 22px; height: 22px; }

/* Cashier badge in the order head - who is signed in, tap to switch.
   Only rendered when timecards is on. */
.kt-order-head .cashier-badge {
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
    padding: 2px 8px;
    border-radius: 6px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: inherit;
    opacity: 0.9;
}

/* Customer picker (Customer Database add-on). The markup and behaviour are the
   shared customer-lookup.js control; only the look lives here, because the
   kitchen register does not load style.css. The class names .hidden and the
   customer-* family are the control's own, so they are styled rather than
   renamed. */
.kt-customer {
  flex: 0 0 auto;
  position: relative;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
}
.kt-customer .customer-picker-search { display: flex; gap: var(--gap); align-items: center; }
.kt-customer input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 40px;
  padding: 6px 10px;
  font-size: 16px;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.kt-customer .kt-mini { padding: 0 10px; font-size: 14px; }
.kt-customer .hidden { display: none; }
.kt-customer .customer-results {
  position: absolute;
  z-index: 20;
  left: 12px;
  right: 12px;
  margin-top: 4px;
  max-height: 240px;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.kt-customer .customer-result {
  display: block;
  width: 100%;
  min-height: 44px;
  text-align: left;
  padding: 10px 14px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-size: 16px;
  cursor: pointer;
}
.kt-customer .customer-result:last-child { border-bottom: none; }
.kt-customer .customer-result:hover,
.kt-customer .customer-result:focus { background: var(--tile-press); }
.kt-customer .customer-result-sub { color: var(--ink-soft); font-size: 13px; margin-left: 8px; }
.kt-customer .customer-result-empty { padding: 10px 14px; color: var(--ink-soft); }
.kt-customer .customer-attached {
  margin-top: 6px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--tile-press);
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
}

/* Loyalty line under the attached customer. */
.kt-loyalty {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  margin-top: 6px;
  font-size: 15px;
  color: var(--ink-soft);
}
.kt-loyalty[hidden] { display: none; }
.kt-loyalty #kt-loyalty-balance { font-weight: 700; color: var(--ink); }
.kt-loyalty-card { padding: 0 10px; font-size: 14px; color: var(--ok); border-color: var(--ok); }

/* Consent box under the attached customer (marketing-consent.js). The
   picker's input rule above is for the search box; a checkbox must not
   inherit its width and height. */
.kt-customer .consent-line {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  font-size: 15px;
  color: var(--ink);
  cursor: pointer;
}
.kt-customer .consent-line input {
  flex: 0 0 auto;
  min-height: 0;
  width: 22px;
  height: 22px;
  padding: 0;
}
.kt-customer .consent-note { color: var(--ink-soft); font-size: 13px; }

/* Offers under the attached customer (marketing-offers.js). */
.kt-customer .offer-line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap); margin-top: 6px; }
.kt-customer .kt-offer { padding: 0 10px; font-size: 14px; color: var(--accent); border-color: var(--accent); }
.kt-customer .offer-applied { font-size: 14px; color: var(--ink-soft); }
.kt-customer .offer-error { font-size: 13px; color: var(--danger); }

.kt-customer .consent-note.consent-warning { color: var(--danger); font-weight: 600; }

/* Open tickets (add-on). */
.kt-btn.kt-send { background: var(--bg); border-color: var(--ok); color: var(--ok); }
/* Label and server badge on the left; the buttons as one group on the right,
   starting at the first of them. Tickets used to carry the auto margin, which
   took all the free space and left everything before it crammed together. */
.kt-order-head .kt-order-more { margin-left: auto; }
.kt-order-head #kt-tips-btn,
.kt-order-head .kt-tickets-btn { padding: 0 10px; font-size: 14px; white-space: nowrap; }
.kt-order-head #kt-count { white-space: nowrap; font-size: 14px; }

/* The manager-PIN prompt (manager-approval.js), in the kitchen's own look -
   its styling otherwise lives in the retail stylesheet this page does not load. */
dialog.modal-panel {
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel); color: var(--ink);
  padding: 18px 20px; max-width: min(420px, 92vw);
}
dialog.modal-panel::backdrop { background: rgba(15, 23, 42, .55); }
dialog.modal-panel h3 { margin: 0 0 8px; }
dialog.modal-panel .hidden { display: none; }
dialog.modal-panel .manager-approval-msg { color: var(--ink-soft); font-size: 14px; }
dialog.modal-panel input { width: 100%; min-height: 44px; font-size: 20px; margin-top: 6px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--ink); padding: 0 10px; }
dialog.modal-panel .modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
dialog.modal-panel button { min-height: 44px; padding: 0 16px; border-radius: 8px; font-weight: 700;
  border: 1px solid var(--line); background: var(--accent, #2563eb); color: #fff; }
dialog.modal-panel button.btn-secondary { background: var(--bg); color: var(--ink); }
.kt-ticket-banner { padding: 8px 12px; font-weight: 800; font-size: 18px; color: var(--on-ok); background: var(--ok); }
.kt-ticket-row { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; width: 100%; text-align: left;
  padding: 12px; margin: 0 0 8px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); color: var(--ink); font-size: 17px; touch-action: manipulation; }
.kt-ticket-row-name { font-weight: 800; }
.kt-ticket-row-total { font-weight: 700; text-align: right; }
.kt-ticket-row-meta { grid-column: 1 / -1; font-size: 14px; opacity: .75; }
.kt-ticket-old { border-color: var(--danger); }
.kt-ticket-old .kt-ticket-row-meta { color: var(--danger); opacity: 1; font-weight: 700; }

/* Split checks. */
.kt-ticket-banner { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.kt-split-btn { background: var(--bg); color: var(--ink); }
.kt-split-bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--bg);
  border-bottom: 1px solid var(--line); font-weight: 700; }
.kt-split-bar span { flex: 1; }
.kt-split-go { background: var(--ok); color: var(--on-ok); border-color: var(--ok); }
.kt-split-pick { cursor: pointer; }
.kt-split-pick.kt-picked { background: var(--mini-press); outline: 2px solid var(--ok); outline-offset: -2px; }

/* Print the check. */
.kt-check-btn { margin-left: auto; margin-right: 8px; }
.kt-check-btn + .kt-tickets-btn { margin-left: 0; }

/* Pay by phone in progress. */
.kt-phone-bar { display: flex; align-items: center; gap: 8px; padding: 8px 12px; font-weight: 700;
  border-bottom: 1px solid var(--line); background: var(--bg); }
.kt-phone-bar span { flex: 1; }

/* Coursing: where each course starts in the order pane. */
.kt-course-head { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--accent); padding: 8px 4px 2px; border-bottom: 1px solid var(--line); }
.kt-ticket-fire { margin: -2px 0 8px auto; display: block; }

/* Tip on the reader / on the slip, and the Tips to enter list. */
.kt-tipmode-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 6px 0; }
/* .kt-row stretches every child; this one keeps its own size. */
.kt-tipmode-row > * { flex: 0 0 auto; }
/* Two halves of one pill, like the language switch, the chosen one filled. */
.kt-tipmode {
  display: inline-flex; gap: 2px; padding: 3px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--bg); cursor: pointer; touch-action: manipulation;
}
.kt-tipmode span {
  min-height: 34px; display: inline-flex; align-items: center;
  padding: 0 16px; border-radius: 999px;
  font-size: 15px; font-weight: 700; color: var(--ink-soft);
}
.kt-tipmode span.active { background: var(--accent); color: var(--accent-ink); }
/* Details on a line of their own, everything you act on underneath: beside
   an input the details were squeezed to a word per line. */
.kt-tip-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.kt-tip-who { flex: 1 1 100%; min-width: 0; font-weight: 600; }
.kt-tip-row input { width: 6.5em; }
.kt-tip-row select { max-width: 100%; }
.kt-tip-entered { flex: 1 1 auto; }
.kt-tip-row .kt-modal-sub, .kt-tip-flag { flex: 1 1 100%; margin: 0; }
.kt-tips-section { margin: 14px 0 4px; }

/* HIDDEN MEANS HIDDEN, everywhere on the kitchen screens. Any class that sets
   display (flex, grid...) beats the browser's own [hidden] { display: none },
   so the element stays on screen after the code hides it. That was fixed one
   class at a time (.kt-check, .kt-attach, .kt-loyalty...) and the next three
   were missed: the pay-by-phone bar stayed up after Cancel (found 2026-10-15),
   and the ticket banner and split bar had the same hole. One rule, so a new
   bar cannot repeat it. */
[hidden] { display: none !important; }

/* A set-aside table has paid by phone: the Tickets button says so until the
   ticket is opened to finish it. */
.kt-tickets-btn.kt-attn { background: var(--ok); border-color: var(--ok); color: var(--on-ok); }

/* Order lines: - and + at full touch size; the dish itself opens note,
   add-on and remove. */
.kt-line { align-items: center; }
.kt-qty .kt-mini { min-width: 44px; min-height: 44px; font-size: 20px; }
.kt-line-tap { cursor: pointer; border-radius: 8px; padding: 2px 4px; touch-action: manipulation; }
.kt-line-tap:active { background: var(--mini-press); }
.kt-line-more { color: var(--ink-soft); margin-left: 6px; font-weight: 800; }
.kt-btn.kt-danger { color: var(--danger); border-color: var(--danger); }
.kt-order-more { font-size: 20px; }

/* Clear: still a full-height target, but quieter than Send and Pay, so it is
   not the button a rushed hand finds first. */
.kt-actions #kt-clear { flex: .8; background: transparent; color: var(--ink-soft); font-weight: 600; }


/* The Clock in/out box (templates/_timecard_widget.html), in the kitchen's
   look: its retail styling lives in style.css, which this page does not load. */
.modal-overlay { position: fixed; inset: 0; z-index: 2000; display: flex;
  align-items: center; justify-content: center; background: rgba(15, 23, 42, .55); padding: 16px; }
.modal-overlay.hidden, #timecard-modal .hidden { display: none; }
.modal-overlay > .modal { background: var(--panel); color: var(--ink); border: 1px solid var(--line);
  border-radius: 14px; padding: 18px 20px; width: min(440px, 100%); max-height: 90vh; overflow: auto; }
.modal-overlay h3 { margin: 0 0 8px; }
.modal-overlay h4 { margin: 12px 0 4px; font-size: 14px; }
.modal-overlay p { margin: 4px 0; }
.modal-overlay .settings-hint { color: var(--ink-soft); font-size: 14px; }
.modal-overlay a { color: var(--accent, #2563eb); }
.modal-overlay input { width: 100%; min-height: 44px; font-size: 20px; margin-top: 6px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--ink); padding: 0 10px; }
.modal-overlay .modal-feedback { min-height: 1.4em; margin-top: 8px; font-weight: 600; }
.modal-overlay .modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; }
.modal-overlay button { min-height: 44px; padding: 0 16px; border-radius: 8px; font-weight: 700;
  border: 1px solid var(--line); background: var(--accent, #2563eb); color: #fff; }
.modal-overlay button.btn-secondary { background: var(--bg); color: var(--ink); }
.timecard-mine-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.timecard-mine-table td { padding: 4px 6px; border-bottom: 1px solid var(--line); }


/* The modifier picker. Wider than the other dialogs - a group of twelve
   options has to fit without becoming a list - and it scrolls inside, so
   Done is always on screen. */
.kt-modal-card.kt-mod-card { width: min(720px, 96vw); max-height: 92vh; display: flex; flex-direction: column; }
.kt-mod-body { overflow-y: auto; flex: 1 1 auto; margin: 4px -4px 0; padding: 0 4px; }
.kt-mod-group { border-top: 1px solid var(--line); padding: 12px 0 8px; }
.kt-mod-group:first-child { border-top: none; padding-top: 4px; }
.kt-mod-nested { border-left: 3px solid var(--accent, #2563eb); border-top: none; padding-left: 12px; margin-top: -4px; }
.kt-mod-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.kt-mod-head strong { font-size: 17px; }
.kt-mod-rule { font-size: 13px; color: var(--ink-soft); white-space: nowrap; }
.kt-mod-rule.kt-mod-required { color: var(--bad, #dc2626); font-weight: 700; }
.kt-mod-rule.kt-mod-ok { color: var(--good, #15803d); font-weight: 700; }
.kt-mod-prefixes { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.kt-chip.kt-mod-prefix { min-height: 36px; font-size: 14px; padding: 0 12px; }
.kt-mod-hint { min-height: 1.3em; color: var(--bad, #dc2626); font-weight: 600; margin: 8px 0 0; }

/* Items screen: the group editor's option rows and the group checklists. */
.kt-modg-row { display: grid; grid-template-columns: minmax(120px, 2fr) 90px 90px minmax(110px, 1.4fr) 56px 40px;
  gap: 6px; align-items: center; margin-bottom: 6px; }
.kt-modg-row input[type="text"], .kt-modg-row input[type="number"], .kt-modg-row select { width: 100%; min-width: 0; }
.kt-modg-row .kt-modg-default { justify-self: center; width: 22px; height: 22px; }
.kt-modg-labels { font-size: 12px; color: var(--ink-soft); text-transform: uppercase; margin-bottom: 2px; }
.kt-mod-pick-head { margin: 14px 0 6px; font-size: 15px; }
.kt-mod-picklist { display: flex; flex-wrap: wrap; gap: 6px 16px; }
@media (max-width: 640px) {
  .kt-modg-row { grid-template-columns: 1fr 80px 80px; }
  .kt-modg-labels { display: none; }
}

/* The order type button: says what the order is, in the accent colour, so a
   wrong one is seen before it is sent. */
.kt-order-head .kt-otype { padding: 0 10px; font-size: 13px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .4px; white-space: nowrap; color: var(--accent, #2563eb); border-color: var(--accent, #2563eb); }

/* A comp on the order line. */
.kt-line-note.kt-line-comp { color: var(--good, #15803d); font-style: normal; font-weight: 700; }
#kt-comp-modal .kt-row { display: flex; gap: 8px; margin: 10px 0; }
#kt-comp-modal input, #kt-void-modal input { width: 100%; min-height: 44px; font-size: 18px; }

/* The card held on a bar tab, beside the ticket's name. */
.kt-ticket-banner { flex-wrap: wrap; }
#kt-ticket-name { flex: 1; }
.kt-tab-badge { order: 9; flex-basis: 100%; font-size: 13px; font-weight: 650; padding: 2px 0 0; }
.kt-tab-badge.kt-tab-flag { color: #ffd8d8; }
.kt-tab-chip { font-weight: 650; }

/* The public demo's banner, above everything. */
.kt-demo-banner { padding: 6px 12px; font-size: 13px; font-weight: 650; text-align: center;
  background: #f5c542; color: #1d1d1d; }
