/* Voxels In One System: what every page stands on, the public shop and the staff pages alike. The shop
   (index.html) loads this and shop.css; every other page this and app.css. Kept to what the shop needs, so
   a visitor on a crowded network waits for as little CSS as can be: the colours of both themes, the reset,
   buttons and fields, simple tables, dialogs and toasts. No external fonts (the CSP allows only 'self').
   The palette (decisions.md, 2026-10-31, "Colour by side"):
     paper and ink   one set for the shop and the staff pages: the page (and dialogs), cards and fields, sunken
                     parts, the picture plate, lines, muted text, ink (text, the focus ring, toasts)
     blue            --action: the staff pages' main buttons and what is selected; never in the shop
     highlight       --hl…: "this, now" on the staff pages (this month, a one-time password), never a button
     meaning         sale types (green on-site, violet online reserved, teal online from stock) and red danger
   The shop's own saffron, the colour of everything that buys, is in shop.css. */
:root{
  --bg:#F6F3EE; --surface:#FFFDF9; --surface-2:#EFEBE4; --plate:#ECE7DF; --ink:#16140F; --muted:#6B655B; --line:#E2DBD0;
  --action:#2B50D8; --action-ink:#FFFFFF; --action-soft:#E9EEFC;
  --hl:#FFF5C7; --hl-strong:#FFE27A; --hl-ink:#463A00;
  --onsite:#1C7A4B; --online:#6B43C4; --spot:#0B6E8A; --danger:#B42318; --focus:var(--ink);
  /* Bars of charts (an event's statistics): the action blue, a step darker in the dark theme so a bar is not lighter than its band. */
  --chart:#2B50D8;
  --shadow:0 1px 2px rgba(26,25,21,.06),0 18px 48px -12px rgba(26,25,21,.24);
  --ring:0 0 0 3px color-mix(in srgb,var(--ink) 11%,transparent);
  /* What shows through the transparent parts of a picture (a logo, a cut-out acrylic stand): in the light theme
     nothing, so the page itself does (a picture's frame drops its waiting plate once the picture is in: shop.css);
     in the dark theme a light plate, since such pictures are mostly drawn for a light page (a black logo would
     vanish on the dark one). */
  --pic-plate:transparent;
  --ease-out:cubic-bezier(.16,1,.3,1);
  /* The rest of the design system's scales (the VIOS design system, tokens.json: the same names). The same in both
     themes. Corners: a stamp, key caps, product pictures, banners and tiles, a switch's choice, controls, boxes,
     what floats, panels, dialogs, the sign-in card, pills. */
  --radius-stamp:3px; --radius-kbd:5px; --radius-pic:6px; --radius-banner:8px; --radius-seg:9px; --radius-control:10px;
  --radius-box:12px; --radius-float:14px; --radius-panel:16px; --radius-modal:18px; --radius-card:22px; --radius-pill:999px;
  /* A button at rest, a panel at rest, the chosen side of a switch raised out of its track. */
  --shadow-rest:0 1px 1px rgba(26,25,21,.04); --shadow-panel:0 1px 2px rgba(26,25,21,.04);
  --shadow-raised:0 1px 2px rgba(26,25,21,.14),0 0 0 .5px rgba(26,25,21,.06);
  /* The mark's three faces, lit from the upper left: the same in both themes. */
  --voxel-lit:#FFE27A; --voxel-face:#F2C230; --voxel-shade:#C98F17;
  /* Type: the app's sans for everything read, a monospace for keys and passwords (the shop's display serif is in shop.css). */
  --font-sans:"Atkinson Hyperlegible Next","Atkinson Hyperlegible",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  color-scheme:light;
  box-sizing:border-box;
  padding-top:env(safe-area-inset-top,0px);
  padding-bottom:env(safe-area-inset-bottom,0px);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#12110F; --surface:#1B1916; --surface-2:#252320; --plate:#201E1B; --ink:#F1ECE3; --muted:#A39C90; --line:#35312B;
    --action:#8CA6FA; --action-ink:#0D1220; --action-soft:#232C48;
    --hl:#332D12; --hl-strong:#5C4D12; --hl-ink:#FFE9A3;
    --onsite:#5CCB91; --online:#B69EF3; --spot:#5CCBE6; --danger:#F2877A; --chart:#6B88EE;
    --shadow:0 1px 2px rgba(0,0,0,.3),0 18px 48px -12px rgba(0,0,0,.7); --pic-plate:#DCD6CB;
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#12110F; --surface:#1B1916; --surface-2:#252320; --plate:#201E1B; --ink:#F1ECE3; --muted:#A39C90; --line:#35312B;
  --action:#8CA6FA; --action-ink:#0D1220; --action-soft:#232C48;
  --hl:#332D12; --hl-strong:#5C4D12; --hl-ink:#FFE9A3;
  --onsite:#5CCB91; --online:#B69EF3; --spot:#5CCBE6; --danger:#F2877A; --chart:#6B88EE;
  --shadow:0 1px 2px rgba(0,0,0,.3),0 18px 48px -12px rgba(0,0,0,.7); --pic-plate:#DCD6CB;
  color-scheme:dark;
}
*,*::before,*::after{box-sizing:border-box}
html{height:100%;scroll-padding-top:env(safe-area-inset-top,0px)}
body{margin:0;min-height:100%;background:var(--bg);color:var(--ink);
  font-family:var(--font-sans);
  font-size:16px;line-height:1.45;-webkit-font-smoothing:antialiased}
button,input,select,textarea{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* Screen-reader-only text. Scroll containers are position:relative so these never widen the page. */
.sr{position:absolute;top:0;left:0;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.boot{padding:40px 20px;text-align:center;color:var(--muted)}
::selection{background:color-mix(in srgb,var(--action) 22%,transparent)}
/* The mark: one voxel, an isometric cube cut from a hexagon, its three faces lit from the upper left. */
.mark{flex:none;display:inline-block;width:22px;height:25px;clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
  background:conic-gradient(from -60deg at 50% 50%,var(--voxel-lit) 0 120deg,var(--voxel-shade) 0 240deg,var(--voxel-face) 0)}
/* buttons & fields */
.btn{white-space:nowrap;border:1px solid var(--line);background:var(--surface);border-radius:var(--radius-control);padding:8px 15px;min-height:44px;font-weight:600;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;text-decoration:none;color:var(--ink);box-shadow:var(--shadow-rest);
  transition:background .15s,border-color .15s,box-shadow .15s,transform .1s,opacity .15s}
.btn:hover{background:var(--surface-2);border-color:color-mix(in srgb,var(--ink) 16%,var(--line))}
.btn:active{transform:translateY(1px)}
/* A staff page's main button (Save, Confirm, Add, Stock, Publish, Sign in): blue, what is important or done often.
   The shop has none: what buys there is saffron (shop.css). */
.btn.primary{background:var(--action);border-color:var(--action);color:var(--action-ink)}
.btn.primary:hover{background:color-mix(in srgb,var(--action) 88%,#fff);border-color:transparent}
.btn.danger{color:var(--danger)}
.btn.danger.solid{background:var(--danger);border-color:var(--danger);color:var(--surface)}
.btn.ghost{border-color:transparent;background:transparent;box-shadow:none}
.btn.ghost:hover{background:color-mix(in srgb,var(--ink) 6%,transparent)}
.btn.sm{min-height:36px;padding:5px 11px;font-size:14px}
.btn:disabled{opacity:.45;cursor:not-allowed;transform:none}
/* display:inline-flex above would otherwise win over the hidden attribute. */
.btn[hidden]{display:none}
select,.field,textarea{border:1px solid var(--line);border-radius:var(--radius-control);background:var(--surface);padding:8px 11px;min-height:44px;transition:border-color .15s,box-shadow .15s}
select:hover,.field:hover,textarea:hover,.search input:hover{border-color:color-mix(in srgb,var(--ink) 22%,var(--line))}
/* Focused: an ink edge and a soft halo, like the shop's (no browser blue). */
select:focus-visible,.field:focus-visible,textarea:focus-visible,.search input:focus-visible{outline:0;border-color:var(--ink);box-shadow:var(--ring)}
/* A list draws its own chevron, two strokes in the muted ink, so it looks the same on every system. */
select,select.field{-webkit-appearance:none;appearance:none;padding-right:34px;cursor:pointer;background-repeat:no-repeat;background-size:6px 6px;
  background-position:calc(100% - 20px) 55%,calc(100% - 14px) 55%;
  background-image:linear-gradient(45deg,transparent 38%,var(--muted) 38%,var(--muted) 62%,transparent 62%),linear-gradient(-45deg,transparent 38%,var(--muted) 38%,var(--muted) 62%,transparent 62%)}
/* A list is never wider than what holds it, however long its longest choice (a row of filters on a phone). */
select{max-width:100%}
select:disabled{cursor:not-allowed;opacity:.55}
main{max-width:1440px;margin:0 auto;padding:20px 20px 100px}
@media (max-width:640px){main{padding:12px 12px 100px}}
.search{position:relative;flex:1 1 260px;max-width:420px}
.search input{width:100%;padding:10px 12px 10px 40px;border:1px solid var(--line);border-radius:var(--radius-control);background:var(--surface);min-height:44px}
.search .ico{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--muted);display:flex}
.actions{display:flex;justify-content:flex-end;align-items:center;gap:8px;flex-wrap:wrap}

/* tables (an order's lines in the shop; every list of the staff pages, whose extras are in app.css) */
table.tbl{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}
.tbl th{font-size:12.5px;color:var(--muted);font-weight:600;text-align:left;padding:11px 16px;border-bottom:1px solid var(--line);white-space:nowrap;letter-spacing:.01em}
.tbl thead th{background:var(--surface-2)}
.tbl td{padding:11px 16px;border-bottom:1px solid var(--line);vertical-align:middle;white-space:nowrap}
.tbl tbody tr:not(.sel):hover td{background:color-mix(in srgb,var(--ink) 2.5%,transparent)}
.tbl tr:last-child td{border-bottom:0}
.tbl td.r,.tbl th.r{text-align:right}
.tbl tfoot td{font-weight:700;border-top:2px solid var(--line);border-bottom:0;background:var(--surface-2)}
@media (max-width:600px){.tbl th,.tbl td{padding-left:11px;padding-right:11px}}
.tbl td.wrap{white-space:normal;min-width:120px}
/* An icon-only button (the "⋯" of more actions, an order bar's close). */
.btn.iconbtn{width:36px;padding:0;color:var(--muted)}
.btn.iconbtn:hover,.btn.iconbtn:has(+ .popmenu:popover-open){color:var(--ink);background:color-mix(in srgb,var(--ink) 6%,transparent)}
.btn.iconbtn .ico{width:20px;height:20px}
.muted{color:var(--muted)}
.err{color:var(--danger);font-weight:600;margin:0}
.ok{color:var(--onsite);font-weight:600;margin:0}
.empty{padding:40px 20px;text-align:center}
.empty p{margin:0 0 14px;color:var(--muted)}
/* A number to read out or copy: a new passcode or password, the shop's order number. */
.big{font-size:36px;font-weight:700;letter-spacing:.1em;text-align:center;padding:14px;border:2px dashed var(--hl-strong);background:var(--hl);color:var(--hl-ink);border-radius:var(--radius-box);margin:0 0 14px;font-variant-numeric:tabular-nums}

/* dialogs */
.overlay{position:fixed;inset:0;background:rgba(18,16,12,.42);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);display:grid;place-items:center;z-index:100;padding:20px}
/* A dialog is the page's own paper, brought forward: the page's colour, a hairline edge (which holds it apart from
   the dimmed page in the dark theme too) and a shadow. What sits on it (fields, lists) keeps its own surface. */
.modal{background:var(--bg);border-radius:var(--radius-modal);max-width:440px;width:100%;padding:24px;box-shadow:0 0 0 1px var(--line),var(--shadow)}
.modal h2{margin:0 0 8px;font-size:20px;letter-spacing:-.015em}
/* Dialogs rise in and fade out (dialogs.js keeps a closing one until its fade ends; it takes no clicks meanwhile). */
@keyframes ov-in{from{opacity:0}}
@keyframes ov-out{to{opacity:0}}
@keyframes modal-in{from{opacity:0;transform:translateY(14px) scale(.98)}}
@keyframes modal-out{to{opacity:0;transform:translateY(6px) scale(.985)}}
.overlay{animation:ov-in .2s ease-out}
.overlay .modal{animation:modal-in .36s var(--ease-out)}
.overlay.closing{pointer-events:none;animation:ov-out .18s ease-in forwards}
.overlay.closing .modal{animation:modal-out .18s ease-in forwards}
@media (prefers-reduced-motion:reduce){.overlay,.overlay .modal,.overlay.closing,.overlay.closing .modal{animation:none}}
.modal p{margin:0 0 16px;color:var(--muted)}
.modal .field{width:100%}
.modal .fld{margin-bottom:14px}
.modal .actions .ok{margin-right:auto}
.modal.wide{max-width:760px;max-height:calc(100dvh - 40px);overflow:auto}
.modal .small{font-size:14px;margin:6px 0 0}

/* toasts */
#toasts{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(20px + env(safe-area-inset-bottom,0px));z-index:90;width:max-content;max-width:calc(100vw - 24px)}
.toast{display:flex;align-items:center;gap:14px;background:var(--ink);color:var(--surface);padding:10px 12px 10px 18px;border-radius:var(--radius-float);box-shadow:var(--shadow);font-weight:600;animation:toast-in .4s var(--ease-out)}
@keyframes toast-in{from{opacity:0;transform:translateY(12px) scale(.96)}}
@media (prefers-reduced-motion:reduce){.toast{animation:none}}
.toast .undo{border:0;background:transparent;color:var(--hl-strong);font-weight:700;padding:6px 10px;border-radius:var(--radius-banner);cursor:pointer;min-height:44px}
.toast .undo:hover{background:rgba(255,255,255,.1)}
