/* ============================================================
   KOZHI — canonical design tokens
   ------------------------------------------------------------
   The ONE place colour, type, spacing and control sizing are
   defined. Every app (guest site, POS, host, KDS, bar, kitchen,
   schedule, driver, order, gift cards, marketing) imports this
   FIRST, then maps its own legacy variable names onto these
   tokens in its local :root block.

   Rules of the road:
   - Never hard-code a hex, a px font-size or a px radius in an
     app stylesheet. Add a token here instead.
   - Both palettes (light + dark) are exposed as plain tokens.
     An app picks the surfaces it needs explicitly. The one
     exception is the shared toast/dialog at the foot of this
     file, which a staff page opts into with
     <html data-kui="dark">.
   - The type scale has 8 steps. There is no step 9. If a size
     "needs" to be between two steps, it doesn't.
   ============================================================ */

:root {
  /* --------------------------------------------------------
     WARM NEUTRAL RAMP
     One hue family end to end, so the guest site and the staff
     tablets read as the same restaurant rather than two products.
     -------------------------------------------------------- */
  --k-warm-000: #ffffff;
  --k-warm-050: #faf7f1;
  --k-warm-100: #f6f3ec;
  --k-warm-200: #ebe4d2;
  --k-warm-300: #d8ccb5;
  --k-warm-400: #b8a584;   /* taupe */
  --k-warm-500: #8a7c65;
  --k-warm-600: #5c5344;
  --k-warm-700: #3a332a;
  --k-warm-800: #2c241d;
  --k-warm-900: #1a1612;   /* ink */
  --k-warm-950: #12100d;

  /* --------------------------------------------------------
     DARK SURFACES (staff apps)
     Warm near-blacks from the same hue family — replaces the
     three unrelated near-blacks the apps each invented
     (#0a0d0c green-black, #0d0d0d neutral, #131816).
     -------------------------------------------------------- */
  --k-dark-bg:       #0f0d0b;
  --k-dark-panel:    #191510;
  --k-dark-panel-2:  #221d16;
  --k-dark-panel-3:  #2b2419;

  --k-dark-text:       #f2ede4;
  --k-dark-text-dim:   rgba(242, 237, 228, 0.64);
  --k-dark-text-faint: rgba(242, 237, 228, 0.38);
  --k-dark-line:       rgba(242, 237, 228, 0.09);
  --k-dark-line-2:     rgba(242, 237, 228, 0.18);

  /* --------------------------------------------------------
     BRAND
     Wine is the accent. It is the ONLY accent for primary
     actions, anywhere in the ecosystem.
     -------------------------------------------------------- */
  --k-wine:        #7a1f2b;
  --k-wine-deep:   #5a161f;
  --k-wine-soft:   #c25e6b;   /* wine as TEXT on a dark surface — 5.0:1 on --k-dark-bg */
  --k-wine-tint:   rgba(122, 31, 43, 0.12);
  --k-taupe:       #b8a584;
  --k-sage:        #7a7a5e;

  /* --------------------------------------------------------
     STATUS
     One set of meanings. `-d` variants are the same meaning
     tuned for dark surfaces (all >= 4.5:1 on --k-dark-bg).
     -------------------------------------------------------- */
  --k-ok:       #2f6f4f;
  --k-warn:     #9a6516;
  --k-danger:   #9e3129;
  --k-info:     #2f5f80;

  --k-ok-d:     #6cc295;
  --k-warn-d:   #e0a848;
  --k-danger-d: #e8776b;
  --k-info-d:   #74b0dc;

  /* --------------------------------------------------------
     PER-APP IDENTITY
     A staff member glancing at a tablet should know which app
     they are looking at. That orientation cue is a thin marker
     (rail, badge) — NOT the button colour. Each app overrides
     --k-app-accent; everything actionable stays wine.
     -------------------------------------------------------- */
  --k-app-accent: var(--k-wine-soft);

  /* --------------------------------------------------------
     TYPE
     -------------------------------------------------------- */
  --k-serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --k-sans:  "Inter", -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --k-mono:  "JetBrains Mono", "IBM Plex Mono", ui-monospace, Menlo, monospace;

  /* 8 steps. 12px is the floor on the guest site; staff apps,
     read at arm's length on a tablet, start at --k-text-sm. */
  --k-text-xs:   12px;
  --k-text-sm:   14px;
  --k-text-base: 16px;
  --k-text-md:   18px;
  --k-text-lg:   22px;
  --k-text-xl:   28px;
  --k-text-2xl:  36px;
  --k-text-3xl:  48px;

  /* Fluid display sizes — headlines only. */
  --k-display-sm: clamp(28px, 4vw, 44px);
  --k-display:    clamp(36px, 6vw, 72px);
  --k-display-lg: clamp(44px, 7vw, 104px);

  /* Muted text in these apps is dimmed with opacity rather than given its
     own colour. Below ~0.62, 12px ink text drops under 4.5:1 on a light
     surface — axe found 35 elements failing exactly that way. These are
     floors, not preferences. */
  --k-dim:   0.72;   /* muted labels, captions, secondary lines */
  --k-dim-2: 0.82;   /* barely muted */

  --k-leading-tight: 1.1;
  --k-leading-snug:  1.35;
  --k-leading-body:  1.55;

  /* Tracking. Used deliberately and sparingly — see the note on
     .k-label below. */
  --k-track-label: 0.16em;
  --k-track-tight: -0.015em;

  /* --------------------------------------------------------
     SPACE — 4px base
     -------------------------------------------------------- */
  --k-space-1:  4px;
  --k-space-2:  8px;
  --k-space-3:  12px;
  --k-space-4:  16px;
  --k-space-5:  24px;
  --k-space-6:  32px;
  --k-space-7:  48px;
  --k-space-8:  64px;
  --k-space-9:  96px;

  --k-gutter: clamp(20px, 4vw, 56px);
  --k-maxw:   1480px;

  /* --------------------------------------------------------
     CONTROLS
     --k-control-h is the floor for anything a finger touches.
     44px is the documented minimum touch target; the staff apps
     run on tablets held at arm's length during service, so this
     is not negotiable there.
     -------------------------------------------------------- */
  --k-control-h:    44px;
  --k-control-h-lg: 56px;
  --k-control-h-xl: 72px;   /* PIN pads, KDS bump bars */

  --k-radius-sm: 4px;
  --k-radius:    8px;
  --k-radius-lg: 14px;
  --k-radius-pill: 999px;

  --k-shadow-sm: 0 1px 2px rgba(26, 22, 18, 0.08);
  --k-shadow:    0 4px 16px rgba(26, 22, 18, 0.12);
  --k-shadow-lg: 0 18px 48px rgba(26, 22, 18, 0.22);

  /* The focus ring every app shares — see the FOCUS block below. */
  --k-focus-ring: 0 0 0 2px var(--k-warm-000), 0 0 0 4px var(--k-wine);
  --k-focus-ring-dark: 0 0 0 2px var(--k-dark-bg), 0 0 0 4px var(--k-wine-soft);

  /* --------------------------------------------------------
     MOTION
     -------------------------------------------------------- */
  --k-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --k-dur-fast: 120ms;
  --k-dur:      200ms;
  --k-dur-slow: 420ms;
}

/* ============================================================
   THE LABEL TREATMENT
   ------------------------------------------------------------
   Small uppercase mono lettering used to be applied to every
   section heading, every field label and every button in the
   ecosystem. It is an accent, not a default: it reads as
   decoration when it is everywhere, and it is hard to read at
   any size. Use .k-label where a true overline is wanted, and
   plain sentence-case text everywhere else. Never on a button.
   ============================================================ */
.k-label {
  font-family: var(--k-mono);
  font-size: var(--k-text-xs);
  letter-spacing: var(--k-track-label);
  text-transform: uppercase;
  font-weight: 500;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   FOCUS
   ------------------------------------------------------------
   There were 639 buttons in this codebase and not one
   :focus-visible rule, so keyboard and switch users had no way
   to tell where they were. 18 rules actively set outline: none.

   The ring is drawn with box-shadow rather than outline for two
   reasons: it clears those 18 rules without having to unpick
   each one, and it follows the element's own border-radius
   instead of boxing a pill button in a rectangle. The
   transparent outline underneath is not decoration — in forced
   -colors mode box-shadow is dropped, and that outline is what
   the ring becomes.

   :focus-visible, not :focus, so a mouse click on a button does
   not leave a ring behind it.
   ============================================================ */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
[contenteditable]:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--k-focus-ring);
}

/* Staff apps declare <html data-kui="dark">, so the ring's inner
   halo matches the surface it is drawn on. */
:root[data-kui="dark"] a:focus-visible,
:root[data-kui="dark"] button:focus-visible,
:root[data-kui="dark"] input:focus-visible,
:root[data-kui="dark"] select:focus-visible,
:root[data-kui="dark"] textarea:focus-visible,
:root[data-kui="dark"] summary:focus-visible,
:root[data-kui="dark"] [tabindex]:focus-visible,
:root[data-kui="dark"] [role="button"]:focus-visible,
:root[data-kui="dark"] [role="tab"]:focus-visible,
:root[data-kui="dark"] [contenteditable]:focus-visible {
  box-shadow: var(--k-focus-ring-dark);
}

@media (forced-colors: active) {
  a:focus-visible,
  button:focus-visible,
  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible,
  [tabindex]:focus-visible,
  [role="button"]:focus-visible {
    outline-color: Highlight;
  }
}

/* ============================================================
   SKIP LINK
   Off-screen until focused, so a keyboard user does not have to
   tab through the whole nav on every page.
   ============================================================ */
.k-skip {
  position: absolute;
  left: var(--k-space-4);
  top: var(--k-space-4);
  z-index: 1002;
  padding: var(--k-space-3) var(--k-space-4);
  background: var(--k-warm-900);
  color: var(--k-warm-050);
  border-radius: var(--k-radius);
  font-family: var(--k-sans);
  font-size: var(--k-text-sm);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}
.k-skip:focus { transform: none; }

/* ============================================================
   VISUALLY HIDDEN
   For live-region text and labels that a screen reader needs and
   the layout does not. Not display:none — that is not announced.
   ============================================================ */
.k-sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   TOAST + CONFIRM  (see /assets/ui.js)
   ------------------------------------------------------------
   Surfaces are declared per page rather than guessed: a staff app
   sets <html data-kui="dark">. Defaults below are the light
   (guest) surfaces, so a page that forgets the attribute still
   renders something legible rather than dark-on-dark.
   ============================================================ */
:root {
  --kui-surface:  var(--k-warm-000);
  --kui-text:     var(--k-warm-900);
  --kui-text-dim: var(--k-warm-600);
  --kui-line:     rgba(26, 22, 18, 0.14);
  --kui-shadow:   var(--k-shadow-lg);
  --kui-accent:   var(--k-wine);
  --kui-ok:       var(--k-ok);
  --kui-bad:      var(--k-danger);
  --kui-warn:     var(--k-warn);
}
:root[data-kui="dark"] {
  --kui-surface:  var(--k-dark-panel-2);
  --kui-text:     var(--k-dark-text);
  --kui-text-dim: var(--k-dark-text-dim);
  --kui-line:     var(--k-dark-line-2);
  --kui-shadow:   0 24px 64px rgba(0, 0, 0, 0.6);
  --kui-accent:   var(--k-wine);
  --kui-ok:       var(--k-ok-d);
  --kui-bad:      var(--k-danger-d);
  --kui-warn:     var(--k-warn-d);
}

/* ---- toasts ---- */
.kui-toasts {
  position: fixed;
  right: var(--k-space-5);
  bottom: var(--k-space-5);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--k-space-2);
  pointer-events: none;
}
.kui-toast {
  pointer-events: auto;
  cursor: pointer;
  max-width: min(420px, calc(100vw - 2 * var(--k-space-5)));
  background: var(--kui-surface);
  color: var(--kui-text);
  border: 1px solid var(--kui-line);
  border-left: 3px solid var(--kui-text-dim);
  border-radius: var(--k-radius);
  box-shadow: var(--k-shadow);
  padding: var(--k-space-3) var(--k-space-4);
  font-family: var(--k-sans);
  font-size: var(--k-text-sm);
  line-height: var(--k-leading-snug);
  /* Several of the messages this replaced were two paragraphs joined
     by \n\n. Honour the break instead of running them together. */
  white-space: pre-line;
  animation: kui-toast-in var(--k-dur) var(--k-ease);
}
.kui-toast--good { border-left-color: var(--kui-ok); }
.kui-toast--bad  { border-left-color: var(--kui-bad); }
.kui-toast--warn { border-left-color: var(--kui-warn); }
.kui-toast--out  { opacity: 0; transition: opacity 180ms var(--k-ease); }
@keyframes kui-toast-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ---- confirm dialog ---- */
.kui-backdrop {
  position: fixed; inset: 0;
  z-index: 1001;
  background: rgba(10, 8, 6, 0.78);
  display: flex; align-items: center; justify-content: center;
  padding: var(--k-space-4);
  animation: kui-fade var(--k-dur-fast) var(--k-ease);
}
@keyframes kui-fade { from { opacity: 0; } to { opacity: 1; } }
.kui-dialog {
  width: min(460px, 100%);
  background: var(--kui-surface);
  color: var(--kui-text);
  border: 1px solid var(--kui-line);
  border-radius: var(--k-radius-lg);
  box-shadow: var(--kui-shadow);
  padding: var(--k-space-5);
  font-family: var(--k-sans);
  animation: kui-dialog-in var(--k-dur) var(--k-ease);
}
@keyframes kui-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: none; }
}
.kui-dialog--danger { border-top: 3px solid var(--kui-bad); }
.kui-dialog-title {
  margin: 0 0 var(--k-space-2);
  font-size: var(--k-text-md);
  font-weight: 600;
  letter-spacing: var(--k-track-tight);
  line-height: var(--k-leading-snug);
}
.kui-dialog-body {
  margin: 0 0 var(--k-space-5);
  font-size: var(--k-text-sm);
  line-height: var(--k-leading-body);
  color: var(--kui-text-dim);
}
.kui-dialog-label {
  display: block;
  margin-bottom: var(--k-space-2);
  font-size: var(--k-text-sm);
  color: var(--kui-text-dim);
}
.kui-dialog-input {
  width: 100%;
  min-height: var(--k-control-h);
  margin-bottom: var(--k-space-5);
  padding: 0 var(--k-space-3);
  background: transparent;
  color: var(--kui-text);
  border: 1px solid var(--kui-line);
  border-radius: var(--k-radius);
  font-family: var(--k-sans);
  font-size: var(--k-text-base);
  letter-spacing: 0.04em;
}
.kui-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--k-space-3);
}
.kui-btn {
  min-height: var(--k-control-h);
  padding: 0 var(--k-space-5);
  border-radius: var(--k-radius);
  border: 1px solid transparent;
  font-family: var(--k-sans);
  font-size: var(--k-text-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
}
.kui-btn--quiet {
  background: transparent;
  color: var(--kui-text);
  border-color: var(--kui-line);
}
.kui-btn--primary { background: var(--kui-accent); color: var(--k-warm-050); }
.kui-btn--danger  { background: var(--k-danger);   color: var(--k-warm-050); }
.kui-btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.kui-btn:focus-visible,
.kui-dialog-input:focus-visible {
  outline: none;
  box-shadow: var(--k-focus-ring);
}
:root[data-kui="dark"] .kui-btn:focus-visible,
:root[data-kui="dark"] .kui-dialog-input:focus-visible {
  box-shadow: var(--k-focus-ring-dark);
}

@media (max-width: 560px) {
  .kui-toasts { left: var(--k-space-4); right: var(--k-space-4); align-items: stretch; }
  .kui-toast  { max-width: none; }
  .kui-dialog-actions { flex-direction: column-reverse; }
  .kui-btn { width: 100%; }
}
