/* ============================================================================
   JSOOR Tech · Repair — UI LAYER (single source of truth for components)
   Requires brand/jsoor-tech.css (tokens). Prefix: js-  ·  Root gets .js-scope

   CONFORMANCE CONTRACT — every component in this file satisfies all five:
     K1 tokens      no colour/space/radius/shadow literal (white ink on charcoal
                    and alpha overlays on charcoal are the only allowed literals)
     K2 elevation   a real shadow from the 3-step scale
     K3 reflection  an inset top highlight so the surface catches light
     K4 micro       hover (fine pointers) + press + focus-visible, all tokenised
     K5 a11y        >=44px target where pressable, AA contrast, reduced-motion safe
   ========================================================================= */

.js-scope { --s1: 4px; --s2: 8px; --s3: 12px; --s4: 18px; --s5: 26px;
  --refl: inset 0 1px 0 oklch(1 0 0 / .55);          /* light-surface reflection */
  --refl-dark: inset 0 1px 0 oklch(1 0 0 / .08);      /* on charcoal */
  --press: scale(.97); }
.dark .js-scope, .js-scope.dark { --refl: inset 0 1px 0 oklch(1 0 0 / .06); }

/* -- The `hidden` attribute actually hides ------------------------------------
   The UA stylesheet's `[hidden] { display: none }` sits in a LOWER cascade
   origin than this file, so ANY author rule that sets `display` silently beats
   it. Every component below sets one — so `el.hidden = true` on a .js-chip or a
   .js-btn did nothing at all, and gated controls stayed on screen. Found on the
   first deploy, where an app that had reached the venue displayed "Offline".
   Gating is the method's sanctioned way to withhold a control, which makes this
   a correctness rule rather than a nicety. -------------------------------- */
[hidden] { display: none !important; }

/* -- K1-K5 base: anything pressable inherits the interaction contract -- */
.js-btn, .js-iconbtn, .js-tab, .js-row, .js-tile, .js-pager button, .js-chip--act, .js-seg-opt {
  font-family: inherit; cursor: pointer;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              color var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              transform var(--dur-press) var(--ease-out);
}
.js-scope :focus-visible { outline: none; box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--accent) !important; border-radius: var(--r-sm); }
.js-scope ::selection { background: var(--accent-soft); color: var(--accent-fg); }

/* -- C01 surfaces -- */
.js-card { background: var(--card); border: 1px solid var(--border); border-radius: var(--r-card); box-shadow: var(--sh-1), var(--refl); }
.js-card--raised { box-shadow: var(--sh-2), var(--refl); }
.js-card--float { box-shadow: var(--sh-3), var(--refl); }
.js-panel { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.js-sunken { background: var(--sunken); border: 1px solid var(--border); border-radius: var(--r-md); box-shadow: inset 0 1px 2px oklch(0 0 0 / .04); }

/* -- C02 slab -- */
.js-slab { position: relative; overflow: hidden; border-radius: var(--r-card); background: var(--char-900); color: #fff; padding: 20px 24px 18px; box-shadow: var(--sh-3), var(--refl-dark); }
.js-slab::before { content: ""; position: absolute; inset: auto -8% -70% 44%; height: 130%; background: radial-gradient(closest-side, var(--accent), transparent 70%); opacity: .2; pointer-events: none; }
.js-slab::after { content: ""; position: absolute; inset: 0 0 auto 0; height: 40%; background: linear-gradient(oklch(1 0 0 / .05), transparent); pointer-events: none; }
.dark .js-slab { background: var(--card); border: 1px solid var(--border); }
.js-slab > * { position: relative; }
.js-slab-label { font-family: var(--font-mono); font-size: var(--t-meta); letter-spacing: .12em; text-transform: uppercase; color: oklch(1 0 0 / .55); display: flex; align-items: center; gap: var(--s2); }
.dark .js-slab-label { color: var(--muted); }
.js-slab-label .live { width: 7px; height: 7px; border-radius: 50%; background: var(--ok-dot); box-shadow: 0 0 0 3px oklch(.6 .1 186 / .25); }
.js-figure { margin-top: 7px; font-size: clamp(2.5rem, 4vw, 3.5rem); font-weight: 600; letter-spacing: -.045em; line-height: .95; color: #fff; display: flex; align-items: baseline; gap: 10px; font-variant-numeric: tabular-nums; }
.dark .js-figure { color: var(--ink); }
.js-figure .cur { font-size: .875rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: oklch(1 0 0 / .5); }
.dark .js-figure .cur { color: var(--muted); }

.js-eyebrow { font-family: var(--font-mono); font-size: .68rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.js-h { font-size: var(--t-h2); font-weight: 600; letter-spacing: -.015em; color: var(--ink); }

/* -- C03 buttons -- */
.js-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); min-height: 44px; padding: 0 16px; border-radius: var(--r-btn); border: 1px solid var(--border-strong); background: var(--card); color: var(--ink); font-size: .9375rem; font-weight: 600; white-space: nowrap; box-shadow: var(--sh-1), var(--refl); }
.js-btn--primary { background: var(--primary); color: var(--primary-fg); border-color: var(--primary); box-shadow: var(--sh-2), var(--refl-dark); }
.js-btn--ghost { border-color: transparent; background: transparent; color: var(--muted); box-shadow: none; }
.js-btn--danger { color: var(--bad-fg); border-color: var(--bad-bd); background: var(--bad-bg); }
.js-btn--sm { min-height: 36px; padding: 0 12px; font-size: var(--t-body); border-radius: var(--r-sm); }
@media (hover: hover) and (pointer: fine) {
  .js-btn:hover:not(:disabled) { border-color: var(--accent); box-shadow: var(--sh-2), var(--refl); }
  .js-btn--primary:hover:not(:disabled) { background: var(--primary-hover); border-color: var(--primary-hover); box-shadow: var(--sh-3), var(--refl-dark); }
  .js-btn--ghost:hover:not(:disabled) { color: var(--ink); background: var(--sunken); box-shadow: var(--sh-1), var(--refl); }
}
.js-btn:active:not(:disabled) { transform: var(--press); box-shadow: var(--sh-1), var(--refl); }
.js-btn:disabled { opacity: .45; cursor: default; transform: none; box-shadow: none; }

/* -- C04 icon button -- */
.js-iconbtn { position: relative; width: 44px; height: 44px; display: grid; place-items: center; border-radius: var(--r-sm); border: 1px solid var(--border); background: var(--card); color: var(--ink-2); box-shadow: var(--sh-1), var(--refl); }
.js-iconbtn--sm { width: 40px; height: 40px; }
@media (hover: hover) and (pointer: fine) { .js-iconbtn:hover { border-color: var(--accent); color: var(--ink); box-shadow: var(--sh-2), var(--refl); } }
.js-iconbtn:active { transform: scale(.96); box-shadow: var(--sh-1), var(--refl); }
.js-iconbtn .ping { position: absolute; top: 9px; inset-inline-end: 10px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 2px var(--card); }

/* -- C05 state chips -- */
.js-chip { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 9px; border-radius: var(--r-pill); font-size: var(--t-meta); font-weight: 600; white-space: nowrap; border: 1px solid var(--neutral-bd); background: var(--neutral-bg); color: var(--neutral-fg); box-shadow: var(--refl); }
.js-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--neutral-dot); flex: none; box-shadow: 0 0 0 2px color-mix(in oklab, currentColor 18%, transparent); }
.js-chip--ok { background: var(--ok-bg); border-color: var(--ok-bd); color: var(--ok-fg); } .js-chip--ok .dot { background: var(--ok-dot); }
.js-chip--info { background: var(--info-bg); border-color: var(--info-bd); color: var(--info-fg); } .js-chip--info .dot { background: var(--info-dot); }
.js-chip--warn { background: var(--warn-bg); border-color: var(--warn-bd); color: var(--warn-fg); } .js-chip--warn .dot { background: var(--warn-dot); }
.js-chip--bad { background: var(--bad-bg); border-color: var(--bad-bd); color: var(--bad-fg); } .js-chip--bad .dot { background: var(--bad-dot); }
.js-chip--frozen { background: var(--frozen-bg); border-color: var(--frozen-bd); color: var(--frozen-fg); } .js-chip--frozen .dot { background: var(--frozen-dot); }
.js-chip--guest { background: var(--guest-bg); border-color: var(--guest-bd); color: var(--guest-fg); } .js-chip--guest .dot { background: var(--guest-dot); }
.js-chip--accent { background: var(--accent-soft); border-color: var(--accent-soft-bd); color: var(--accent-fg); } .js-chip--accent .dot { background: var(--accent); }
.js-chip--mono { font-family: var(--font-mono); font-weight: 500; font-size: .66rem; }
.js-chip--act { min-height: 32px; padding: 0 12px; }
@media (hover: hover) and (pointer: fine) { .js-chip--act:hover { border-color: var(--accent); box-shadow: var(--sh-1), var(--refl); } }
.js-chip--act:active { transform: scale(.96); }

/* -- C06 tabs / segmented -- */
.js-tabs { display: inline-flex; gap: 2px; padding: 3px; background: var(--sunken); border: 1px solid var(--border); border-radius: var(--r-pill); box-shadow: inset 0 1px 2px oklch(0 0 0 / .04); }
.js-tab { display: inline-flex; align-items: center; gap: var(--s2); min-height: 34px; padding: 0 13px; border: 0; background: transparent; border-radius: var(--r-pill); color: var(--muted); font-size: .875rem; font-weight: 500; white-space: nowrap; }
.js-tab span { font-family: var(--font-mono); font-size: .7rem; color: var(--faint); }
.js-tab.is-on { background: var(--card); color: var(--ink); font-weight: 600; box-shadow: var(--sh-1), var(--refl); }
.js-tab.is-on span { color: var(--accent-fg); }
@media (hover: hover) and (pointer: fine) { .js-tab:not(.is-on):hover { color: var(--ink); background: color-mix(in oklab, var(--card) 60%, transparent); } }
.js-tab:active { transform: scale(.98); }
.js-seg { display: grid; grid-auto-flow: column; gap: 6px; padding: 4px; background: var(--sunken); border: 1px solid var(--border); border-radius: var(--r-pill); box-shadow: inset 0 1px 2px oklch(0 0 0 / .04); }
.js-seg-opt { position: relative; display: grid; place-items: center; min-height: 40px; border-radius: var(--r-pill); font-size: .9375rem; font-weight: 600; color: var(--muted); }
.js-seg-opt input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.js-seg-opt:has(input:checked) { background: var(--card); color: var(--ink); box-shadow: var(--sh-1), var(--refl); }
.js-seg-opt--ok:has(input:checked) { color: var(--ok-fg); } .js-seg-opt--bad:has(input:checked) { color: var(--bad-fg); }
.js-seg-opt:active { transform: scale(.98); }

/* -- C07 pager -- */
.js-pager { display: inline-flex; align-items: center; gap: var(--s1); }
.js-pager button { width: 34px; height: 34px; display: grid; place-items: center; border-radius: var(--r-sm); border: 1px solid var(--border); background: var(--card); color: var(--ink-2); box-shadow: var(--sh-1), var(--refl); }
.js-pager button:disabled { opacity: .4; cursor: default; box-shadow: none; }
@media (hover: hover) and (pointer: fine) { .js-pager button:not(:disabled):hover { border-color: var(--accent); color: var(--ink); box-shadow: var(--sh-2), var(--refl); } }
.js-pager button:not(:disabled):active { transform: scale(.94); }
.js-pager > span { font-family: var(--font-mono); font-size: var(--t-meta); color: var(--muted); min-width: 32px; text-align: center; }

/* -- C08 table head + rows -- */
.js-thead { display: grid; align-items: center; gap: var(--s3); padding: 8px 18px; background: var(--sunken); border-bottom: 1px solid var(--border); font-family: var(--font-mono); font-size: .64rem; letter-spacing: .11em; text-transform: uppercase; color: var(--muted); box-shadow: var(--refl); }
.js-rows { flex: 1; min-height: 0; display: grid; grid-auto-rows: minmax(44px, 1fr); overflow: hidden; }
.js-row { position: relative; display: grid; align-items: center; gap: var(--s3); padding: 0 18px; min-height: 44px; border: 0; border-top: 1px solid var(--hairline); background: transparent; text-align: start; color: var(--ink); }
.js-row:first-child { border-top: 0; }
.js-row::before { content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: 3px; background: var(--accent); opacity: 0; transition: opacity var(--dur) var(--ease); }
@media (hover: hover) and (pointer: fine) {
  .js-row:hover { background: var(--sunken); }
  .js-row:hover::before { opacity: 1; }
  .js-row:hover .js-go { color: var(--accent-fg); transform: translateX(3px); }
  .js-row:hover .js-progress i { background: var(--accent); }
}
.js-row:active { background: var(--sunken); transform: scale(.999); }
.js-row:focus-visible { box-shadow: inset 0 0 0 2px var(--accent) !important; border-radius: 2px; }
.js-name b { display: block; font-size: .9375rem; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.js-name span { display: block; font-size: var(--t-meta); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.js-num { text-align: end; font-variant-numeric: tabular-nums; font-size: .9375rem; white-space: nowrap; }
.js-num--quiet { color: var(--muted); font-weight: 500; }
.js-num--lead { font-weight: 600; color: var(--ink); letter-spacing: -.01em; }
.js-num--bad { color: var(--bad-fg); font-weight: 600; }
.js-num--ok { color: var(--ok-fg); font-weight: 600; }
.js-go { color: var(--faint); display: inline-grid; place-items: center; transition: transform var(--dur) var(--ease-out), color var(--dur) var(--ease); }
[dir="rtl"] .js-go { transform: scaleX(-1); }

/* -- C09 progress -- */
.js-progress { height: 5px; border-radius: var(--r-pill); background: var(--sunken); border: 1px solid var(--border); overflow: hidden; box-shadow: inset 0 1px 1px oklch(0 0 0 / .05); }
.js-progress i { display: block; height: 100%; background: var(--ok-dot); box-shadow: var(--refl); transition: background-color var(--dur) var(--ease), width var(--dur-pop) var(--ease-out); }

/* -- C10 tile -- */
.js-tilegrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); grid-auto-rows: minmax(112px, max-content); gap: var(--s3); align-content: start; }
.js-tile { position: relative; display: flex; flex-direction: column; min-height: 112px; padding: 12px 13px 11px; border-radius: 14px; background: var(--card); border: 1px solid var(--border); box-shadow: var(--sh-1), var(--refl); text-align: start; color: var(--ink); overflow: hidden; }
.js-tile::after { content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: 3px; background: var(--accent); opacity: 0; transition: opacity var(--dur) var(--ease); }
@media (hover: hover) and (pointer: fine) { .js-tile:hover:not(.is-out) { border-color: var(--border-strong); box-shadow: var(--sh-2), var(--refl); transform: translateY(-1px); } .js-tile:hover::after { opacity: 1; } }
.js-tile:active:not(.is-out) { transform: scale(.985); box-shadow: var(--sh-1), var(--refl); }
.js-tile-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--s2); min-width: 0; }
.js-tile-name { margin-top: 7px; font-size: .92rem; font-weight: 600; line-height: 1.25; letter-spacing: -.01em; overflow-wrap: anywhere; }
.js-tile-foot { margin-top: auto; padding-top: 10px; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s2); }
.js-price { font-weight: 700; font-size: 1.2rem; letter-spacing: -.025em; line-height: 1; font-variant-numeric: tabular-nums; }
.js-price small { font-size: .6rem; font-weight: 600; color: var(--muted); margin-inline-start: 3px; letter-spacing: .04em; }
.js-tile.is-out { cursor: default; background: repeating-linear-gradient(135deg, var(--card) 0 7px, var(--sunken) 7px 14px); box-shadow: none; }
.js-tile.is-out .js-tile-name, .js-tile.is-out .js-price { color: var(--muted); }

/* -- C11 fields -- */
.js-field { display: flex; flex-direction: column; gap: 6px; }
.js-label { font-family: var(--font-mono); font-size: .66rem; letter-spacing: .11em; text-transform: uppercase; color: var(--muted); }
.js-hint { font-size: var(--t-meta); color: var(--faint); }
.js-input { width: 100%; min-height: 46px; padding: 0 13px; font-family: inherit; font-size: 1rem; color: var(--ink); background: var(--sunken); border: 1.5px solid var(--border-strong); border-radius: var(--r-input); box-shadow: inset 0 1px 2px oklch(0 0 0 / .05); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background-color var(--dur) var(--ease); }
.js-input::placeholder { color: var(--faint); }
@media (hover: hover) and (pointer: fine) { .js-input:hover:not(:focus) { border-color: var(--muted); } }
.js-input:focus { outline: none; border-color: var(--accent); background: var(--card); box-shadow: 0 0 0 3px var(--ring), var(--refl) !important; }
select.js-input { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%); background-position: calc(100% - 18px) 21px, calc(100% - 13px) 21px; background-size: 5px 5px; background-repeat: no-repeat; padding-inline-end: 34px; }
.js-amount { position: relative; display: block; }
.js-amount .js-input { padding-inline-end: 48px; font-family: var(--font-mono); font-weight: 600; font-size: 1.125rem; text-align: end; }
.js-amount small { position: absolute; inset-inline-end: 13px; inset-block-start: 50%; transform: translateY(-50%); font-size: .7rem; font-weight: 600; letter-spacing: .06em; color: var(--faint); pointer-events: none; }

/* -- C12 dialog -- */
.js-dialog { position: fixed; inset: 0; z-index: 900; display: grid; place-items: center; padding: 24px; }
.js-dialog-scrim { position: absolute; inset: 0; background: color-mix(in oklab, var(--char-950) 55%, transparent); opacity: 0; transition: opacity var(--dur-pop) var(--ease-out); }
.js-dialog.is-on .js-dialog-scrim { opacity: 1; }
.js-dialog-panel { position: relative; width: min(520px, 100%); max-height: calc(100vh - 48px); display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--border-strong); border-radius: var(--r-card); box-shadow: var(--sh-3), var(--refl); opacity: 0; transform: scale(.97); transition: opacity var(--dur-pop) var(--ease-out), transform var(--dur-pop) var(--ease-out); }
.js-dialog.is-on .js-dialog-panel { opacity: 1; transform: none; }

/* -- C13 toast -- */
.js-toast { position: fixed; inset-block-end: 26px; inset-inline-start: 50%; z-index: 950; display: inline-flex; align-items: center; gap: var(--s2); padding: 12px 20px; border-radius: var(--r-pill); background: var(--primary); color: var(--primary-fg); font-size: .9375rem; font-weight: 600; box-shadow: var(--sh-3), var(--refl-dark); opacity: 0; transform: translateX(-50%) translateY(12px); transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out); pointer-events: none; }
.js-toast.is-on { opacity: 1; transform: translateX(-50%); }

/* -- C14 empty -- */
.js-empty { display: grid; place-items: center; align-content: center; gap: 5px; padding: 22px; text-align: center; color: var(--muted); font-size: .9375rem; }
.js-empty b { color: var(--ink); font-weight: 600; } .js-empty span { font-size: var(--t-body); color: var(--faint); }

/* -- C15 avatar / count -- */
.js-avatar { width: 34px; height: 34px; flex: none; display: grid; place-items: center; border-radius: 50%; background: var(--primary); color: var(--primary-fg); font-weight: 600; font-size: var(--t-meta); box-shadow: var(--sh-1), var(--refl-dark); }
.js-count { font-family: var(--font-mono); font-size: .7rem; font-weight: 500; color: var(--muted); background: var(--sunken); border: 1px solid var(--border); border-radius: var(--r-pill); padding: 2px 9px; box-shadow: var(--refl); }
.js-count--accent { color: var(--accent-fg); background: var(--accent-soft); border-color: var(--accent-soft-bd); }

/* -- K5 reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .js-scope *, .js-dialog *, .js-toast { animation: none !important; transition-property: opacity, color, background-color, border-color, box-shadow !important; }
  .js-dialog-panel { transform: none !important; }
  .js-toast { transform: translateX(-50%) !important; }
  .js-btn:active, .js-tile:active, .js-row:active, .js-iconbtn:active, .js-tab:active, .js-pager button:active { transform: none !important; }
}

/* ============================================================================
   PATTERN A/B SCAFFOLD — the layout grammar, added in consolidation.
   These are not new components. They are the three boxes every surface uses,
   so a new build does not reinvent "slab -> board -> rail" in local CSS.
   ========================================================================= */
.js-surface { height: 100dvh; display: flex; flex-direction: column; overflow: hidden; padding-block-start: var(--jshell-h, 0px); }
.js-stage { flex: 1; min-height: 0; display: grid; gap: var(--s-4); padding: var(--s-4); grid-template-columns: minmax(0, 1fr) 320px; grid-template-rows: auto minmax(0, 1fr); grid-template-areas: "slab rail" "board rail"; }
.js-stage > .js-slab { grid-area: slab; }
.js-stage > .js-board { grid-area: board; min-height: 0; }
.js-stage > .js-rail { grid-area: rail; min-height: 0; display: flex; flex-direction: column; gap: var(--s-4); }
.js-stage--noRail { grid-template-columns: minmax(0, 1fr); grid-template-areas: "slab" "board"; }
.js-stage--noSlab { grid-template-rows: minmax(0, 1fr); grid-template-areas: "board rail"; }
/* Law 1: the rail is the first thing to go. */
@media (max-width: 1080px) {
  .js-stage { grid-template-columns: minmax(0, 1fr); grid-template-areas: "slab" "board"; }
  .js-stage > .js-rail { display: none; }
}
