/* The shared layer every screen inherits — except the register.
 *
 * Jamal: "I want it to be just like Apple. So every single page apart from the
 * POS… all the team pages, all the inventory, all the back end stuff, all the
 * QR code, but just not the actual physical POS till register because the
 * register is quite good already."
 *
 * So this file is loaded by the back office, the QR pages and the staff app,
 * and the register's own rules are left alone. Nothing here is scoped to a
 * screen: a shared layer that each screen has to opt into is a shared layer
 * that drifts.
 *
 * The half that is arithmetic — springs, momentum, tracking — is in
 * worker/src/motion.js and reaches the browser as HP_MOTION. This file is the
 * half that belongs in CSS: the materials, the type scale, and the three
 * accessibility preferences.
 */

:root {
  /* --- Materials -------------------------------------------------------------
   * Translucency is not decoration. A sheet you can see the list through keeps
   * the context of where you were, which is the difference between a panel that
   * covers the screen and one that sits above it.
   *
   * Saturation is pushed past 100% on purpose: a plain blur of a colourful page
   * goes grey, and the material should carry a hint of what is behind it. */
  --mat-blur: 20px;
  --mat-sat: 180%;
  /* **Built from the app's own surface, not from white.** The first version of
   * this file used white translucency, which is Apple's light material — and
   * the back office is dark (`--bg: #0f1115`). A white sheet over a dark list
   * is not a material, it is a mistake that only shows up on a screen.
   *
   * `color-mix` keeps these tied to the token rather than to a hex I copied
   * out of it, so a venue that re-themes gets a material that follows. */
  --mat-thin: color-mix(in srgb, var(--surface, #171a21) 72%, transparent);
  --mat-regular: color-mix(in srgb, var(--surface, #171a21) 86%, transparent);
  --mat-thick: color-mix(in srgb, var(--surface, #171a21) 94%, transparent);
  --mat-border: color-mix(in srgb, var(--border, #2a2f3a) 80%, transparent);
  --mat-shadow: 0 10px 40px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.3);

  /* --- Motion ----------------------------------------------------------------
   * CSS cannot run a spring, so these are the closest cubic-bézier to the
   * springs in motion.js — used for the small, non-interruptible things
   * (a hover, a colour change) where a real spring would be overkill.
   *
   * **Anything a finger can interrupt uses HP_MOTION instead**, because a
   * bézier has a fixed duration decided before the gesture started. */
  --ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-snappy: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-snappy: 180ms;
  --dur-standard: 320ms;

  /* --- Type ------------------------------------------------------------------
   * Tracking per size, from the same table as motion.js `trackingFor`. Kept in
   * both places on purpose: CSS needs it as a constant, the browser needs it as
   * a function for sizes that are computed. */
  --track-11: 0.006em;
  --track-13: 0.002em;
  --track-15: 0em;
  --track-17: -0.002em;
  --track-22: -0.008em;
  --track-28: -0.013em;
  --track-34: -0.017em;
  --track-48: -0.021em;
}

/* Size-specific tracking, applied by size rather than by element, so a heading
 * that happens to be set at body size is spaced like body text. */
.ap-t11 { font-size: 11px; letter-spacing: var(--track-11); }
.ap-t13 { font-size: 13px; letter-spacing: var(--track-13); }
.ap-t15 { font-size: 15px; letter-spacing: var(--track-15); }
.ap-t17 { font-size: 17px; letter-spacing: var(--track-17); }
.ap-t22 { font-size: 22px; letter-spacing: var(--track-22); }
.ap-t28 { font-size: 28px; letter-spacing: var(--track-28); }
.ap-t34 { font-size: 34px; letter-spacing: var(--track-34); }
.ap-t48 { font-size: 48px; letter-spacing: var(--track-48); }

/* **Not mapped by element.** The first version of this file set `h1` to the
 * 34px tracking, and the audit found this app's `h1` is 22px — so every page
 * title was being tightened by twice what it should have been. An element name
 * is not a size, and mapping one to the other is the exact mistake this table
 * exists to prevent.
 *
 * The classes above are for markup that knows its own size. Everything already
 * on screen is handled at runtime by `applyTracking()` in public/js/app.js,
 * which reads the *computed* size and asks HP_MOTION.trackingFor for the
 * answer — so it stays right when a size changes. */

/* --- Materials as a component ----------------------------------------------- */

.ap-material {
  background: var(--mat-regular);
  -webkit-backdrop-filter: blur(var(--mat-blur)) saturate(var(--mat-sat));
  backdrop-filter: blur(var(--mat-blur)) saturate(var(--mat-sat));
  border: 1px solid var(--mat-border);
  box-shadow: var(--mat-shadow);
}
.ap-material.thin { background: var(--mat-thin); }
.ap-material.thick { background: var(--mat-thick); }

/* --- Press ------------------------------------------------------------------
 *
 * **Respond on pointer-down, not on click.** A click fires after the finger
 * lifts, which on a touch screen is 100–300ms after the person believes they
 * pressed the thing. Nothing about that delay is visible in code review and all
 * of it is visible in the hand.
 *
 * `:active` fires on pointer-down for free, so this needs no JavaScript — but
 * it does need `touch-action` set, or the browser holds the state back while it
 * works out whether the gesture is a scroll. */
.ap-press {
  touch-action: manipulation;
  transition: transform var(--dur-snappy) var(--ease-snappy),
              opacity var(--dur-snappy) var(--ease-snappy);
}
.ap-press:active { transform: scale(0.97); opacity: 0.88; }

/* **A control does not inherit the page's font** (v5.518.1). `font-family` is
 * one of the few properties a form control does not take from its parent — the
 * browser hands it its own. `styles.css` says `font-family: inherit` for
 * `input, select, textarea` and **leaves `button` out**, which is the control
 * this product has most of, so every button on every surface rendered in Arial
 * beside text set in the system stack: 227 of them across the back office, the
 * guest QR pages, the register and the kitchen screen.
 *
 * Only the family is inherited. Size and weight are deliberately left alone —
 * buttons set their own, and taking those too would resize the whole product.
 * This is unscoped on purpose, the register included: it is not the Apple
 * restyle the rest of this file is careful to keep off the till, it is the till
 * using the same typeface as the words next to it. */
button, input, select, textarea, optgroup { font-family: inherit; }

/* Buttons already in the product get it without being rewritten. Scoped away
 * from the register — Jamal is happy with how that feels and a scale on a till
 * button pressed fifty times a shift is somebody else's idea of an improvement. */
body:not(.pos-open) .btn,
body:not(.pos-open) button.go,
body:not(.pos-open) .addbtn {
  touch-action: manipulation;
  transition: transform var(--dur-snappy) var(--ease-snappy),
              filter var(--dur-snappy) var(--ease-snappy);
}
body:not(.pos-open) .btn:active,
body:not(.pos-open) button.go:active,
body:not(.pos-open) .addbtn:active { transform: scale(0.97); }

/* --- The three preferences ---------------------------------------------------
 *
 * Three separate requests, answered separately. Somebody who gets motion sick
 * still wants the blur; somebody who cannot read grey on grey still wants the
 * animation. See `respect()` in worker/src/motion.js. */

@media (prefers-reduced-motion: reduce) {
  /* **Not "no animation" — no travel.** Things still change, they just
   * cross-fade in place. Removing the transition entirely makes it impossible
   * to see what changed, which is a different accessibility problem. */
  :root { --dur-snappy: 1ms; --dur-standard: 120ms; }
  .ap-press:active,
  body:not(.pos-open) .btn:active,
  body:not(.pos-open) button.go:active,
  body:not(.pos-open) .addbtn:active { transform: none; }
  .ap-slide, .ap-rise { animation: none !important; }
}

@media (prefers-reduced-transparency: reduce) {
  /* The blur goes, the material stays. A panel with no background at all is
   * unreadable over a list. */
  :root {
    --mat-thin: var(--surface, #171a21);
    --mat-regular: var(--surface, #171a21);
    --mat-thick: var(--surface, #171a21);
  }
  .ap-material {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@media (prefers-contrast: more) {
  :root { --mat-border: var(--text, #e6e9ef); }
  .ap-material { border-width: 1.5px; }
  .ap-press:focus-visible,
  body:not(.pos-open) .btn:focus-visible { outline: 3px solid currentColor; outline-offset: 2px; }
}

/* The guest QR pages are light and do not define --surface, so they take the
 * fallback above (#171a21) and would get a dark sheet on a white page. They
 * declare their own here instead — one line, rather than a second copy of the
 * whole material system. */
body.qr-light {
  --surface: #ffffff;
  --border: rgba(0, 0, 0, 0.10);
  --mat-shadow: 0 10px 40px rgba(0, 0, 0, 0.16), 0 2px 8px rgba(0, 0, 0, 0.08);
  /* **The materials are re-declared, not just the surface they are built from.**
   * A custom property substitutes where it is *declared*, not where it is used —
   * so `--mat-regular` sitting on `:root` resolves `var(--surface)` against
   * `:root`, and overriding `--surface` down here changed nothing at all. The
   * audit caught this: the guest page was serving the dark material on a white
   * background and looked, at a glance, like it was working. */
  --mat-thin: color-mix(in srgb, #ffffff 72%, transparent);
  --mat-regular: color-mix(in srgb, #ffffff 86%, transparent);
  --mat-thick: color-mix(in srgb, #ffffff 94%, transparent);
  --mat-border: rgba(0, 0, 0, 0.10);
}

/* A keyboard always gets a ring, whatever the contrast setting — a focus style
 * that only exists for people who asked for more contrast is not a focus style. */
.ap-press:focus-visible { outline: 2px solid var(--primary, #3b6ff5); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   The kiosk posture (v5.38.0)

   A screen that stays in the building. Only what genuinely differs from a
   phone: bigger targets because nobody is holding it, no hover because there
   is no pointer, and two overlays — the attract screen and the "still there?"
   warning. Everything else is the guest page unchanged, which is the point.
   --------------------------------------------------------------------------- */

/* No hover state is reachable on a fixed touch screen, and a stuck one reads
   as a selection somebody did not make. */
@media (hover: none) {
  .kiosk a:hover, .kiosk button:hover { background: inherit; }
}

/* Standing up, at arm's length, often with a coat over one arm. */
.kiosk button, .kiosk .sheet-row, .kiosk .btn { min-height: 52px; }
.kiosk { -webkit-user-select: none; user-select: none; }

/* "Still there?" — the one thing on the screen with a deadline, so it sits
   above everything including the basket bar and the sheets. */
.kiosk-warn {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 22px; z-index: 9000;
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; border-radius: 16px;
  background: rgba(20, 22, 28, .92); color: #fff;
  border: 1px solid rgba(255, 255, 255, .14);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
  font-size: 17px; max-width: min(92vw, 620px);
}
.kiosk-warn[hidden] { display: none; }
.kiosk-warn .kw-stay {
  border: 0; border-radius: 999px; padding: 12px 20px; font-size: 16px; font-weight: 600;
  background: #fff; color: #14161c; cursor: pointer; white-space: nowrap;
}

/* The attract screen. Covers everything, dismissed by touching anywhere —
   a kiosk that needs one particular button first is a kiosk people walk past. */
.kiosk-attract {
  position: fixed; inset: 0; z-index: 9500;
  display: flex; align-items: center; justify-content: center;
  background: rgba(12, 14, 18, .82);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  backdrop-filter: blur(18px) saturate(150%);
  text-align: center; color: #fff; cursor: pointer;
}
.kiosk-attract[hidden] { display: none; }
.kiosk-attract .ka-big {
  font-size: clamp(44px, 9vw, 96px); font-weight: 700; letter-spacing: -.03em; line-height: 1.05;
}
.kiosk-attract .ka-sub { margin-top: 14px; font-size: clamp(17px, 2.4vw, 24px); opacity: .8; }
/* Breathes, so a passer-by can tell it is awake. Removed entirely for anyone
   who has asked for less motion — the words are the point, not the pulse. */
.kiosk-attract .ka-inner { animation: ka-breathe 3.4s ease-in-out infinite; }
@keyframes ka-breathe {
  0%, 100% { transform: scale(1); opacity: .96; }
  50% { transform: scale(1.028); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .kiosk-attract .ka-inner { animation: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .kiosk-attract { background: #0c0e12; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
