/* ============================================================================
   Retails back-office — "warm boutique" design-system seed.
   Tokens are the approved Claude Design values; keep every layout rule
   direction-agnostic (logical properties only — never left/right).
   ========================================================================== */

:root {
  /* Palette */
  --bg: #faf6f0;
  --ink: #33291f;
  --muted: #8c7a63;
  --secondary: #5c4d3c;
  --accent: #b4531f;
  --accent-soft: #b4531f14;
  --success: #4f7a5c;
  --success-soft: #4f7a5c14;
  --danger: #a03a2e;
  --danger-soft: #a03a2e14;
  --warn: #a8722a;
  --warn-soft: #a8722a1a;
  --border: #e6dccd;
  --divider: #f0e9dd;
  --surface: #ffffff;

  /* Shape */
  --radius-card: 14px;
  --radius-button: 12px;

  /* Type */
  --font: "Tajawal", -apple-system, "Segoe UI", Tahoma, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
}

a { color: var(--accent); text-decoration: none; }

h1, h2, h3 { margin: 0; font-weight: 700; }

/* ---------- App shell ---------- */

.shell {
  display: grid;
  grid-template-columns: 248px 1fr;
  min-height: 100vh;
}

.sidebar {
  border-inline-end: 1px solid var(--border);
  background: var(--surface);
  padding: 1rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.65rem 1rem;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--ink);
}

.brand-mark {
  inline-size: 34px;
  block-size: 34px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 800;
}

.sidebar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.nav-sections { display: contents; }

/* The phone menu button. Hidden on a desktop, where the sidebar is always open and a control
   that only ever says "expanded" is a control with nothing to say. */
.nav-toggle { display: none; }

/* A sidebar section: the module heading plus its links (docs/01 §5 module map).
   No letter-spacing and no text-transform on the heading — both are LTR typographic habits that
   damage Arabic, which is cursive: letter-spacing pulls the joined letterforms apart. Size and
   weight carry the hierarchy instead, so one rule serves both scripts (i18n-rtl.md). */
.nav-group {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}

.nav-group + .nav-group { margin-block-start: 0.35rem; }

.nav-section {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding-block-end: 0.5rem;
}

/* Author `display` beats the UA stylesheet's `[hidden] { display: none }` whatever the
   specificity, so a class that sets `display` on an element the markup also marks `hidden`
   un-hides it. The collapsed sections stay in the DOM (aria-controls points at them), so this
   rule is what actually folds them away. */
.nav-section[hidden] { display: none; }

/* The heading is a real <button>, so it is focusable, space/enter operable and announced with
   its expanded state for free. These rules only undo the browser's button chrome. */
.nav-group-title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  inline-size: 100%;
  margin: 0;
  padding: 0.4rem 0.65rem;
  border: 0;
  border-radius: var(--radius-button);
  background: none;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--muted);
  text-align: start;
  cursor: pointer;
}

.nav-group-title:hover { background: var(--divider); color: var(--secondary); }

/* The caret is a directional icon and mirrors in RTL (i18n-rtl.md), but the flip happens in the
   markup — NavMenu.Caret picks ▸ or ◂ from the culture — so this stylesheet stays free of
   direction-specific rules like the rest of it. Nothing here needs to know which way it points. */
.nav-caret {
  font-size: 0.6rem;
  line-height: 1;
  color: var(--muted);
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.65rem;
  border-radius: var(--radius-button);
  color: var(--secondary);
  font-weight: 500;
}

.nav-link:hover { background: var(--divider); }

.nav-link.active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 700;
}

.nav-link .nav-icon { inline-size: 1.25rem; text-align: center; }

.nav-link.locked { color: var(--muted); }

.lock-hint {
  margin-inline-start: auto;
  font-size: 0.72rem;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  white-space: nowrap;
}

.main { display: flex; flex-direction: column; min-inline-size: 0; }

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.7rem 1.4rem;
  border-block-end: 1px solid var(--border);
  background: var(--surface);
  flex-wrap: wrap;
}

.topbar .spacer { flex: 1; }

.select {
  font-family: var(--font);
  font-size: 0.9rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-button);
  padding: 0.4rem 0.7rem;
}

.btn {
  font-family: var(--font);
  font-size: 0.9rem;
  font-weight: 700;
  border-radius: var(--radius-button);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--secondary);
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.btn:hover { border-color: var(--muted); }

.btn-accent {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg);
}

.avatar {
  inline-size: 30px;
  block-size: 30px;
  border-radius: 50%;
  background: var(--success);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 0.8rem;
  font-weight: 700;
}

.user-chip .who { display: flex; flex-direction: column; line-height: 1.15; }
.user-chip .who .name { font-size: 0.85rem; font-weight: 700; }
.user-chip .who .tenant { font-size: 0.72rem; color: var(--muted); }

.dev-stub-badge {
  font-size: 0.68rem;
  color: var(--warn);
  background: var(--warn-soft);
  border-radius: 999px;
  padding: 0.05rem 0.45rem;
}

/* Development anonymous fallback (V7): the chip must never pass for a signed-in user. */
.user-chip-stub { border: 1px dashed var(--warn); background: var(--warn-soft); }
.user-chip-stub .avatar { background: var(--warn); color: #fff; }
.user-chip-stub .who .name { font-size: 0.78rem; font-weight: 700; color: var(--warn); }

/* Mock ORG-2 data (V3): a human must never mistake fabricated rows for the API's. */
.demo-data-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-block-start: 0.5rem;
  padding: 0.3rem 0.7rem;
  border: 1px dashed var(--warn);
  border-radius: 999px;
  color: var(--warn);
  background: var(--warn-soft);
  font-size: 0.8rem;
  font-weight: 700;
}

/* ---------- Page + cards ---------- */

.page { padding: 1.4rem; display: flex; flex-direction: column; gap: 1.1rem; }

.page-head { display: flex; align-items: baseline; gap: 0.8rem; flex-wrap: wrap; }
.page-head h1 { font-size: 1.35rem; }
.page-note { color: var(--muted); font-size: 0.82rem; }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 1rem 1.1rem;
  min-inline-size: 0;
}

.card-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-block-end: 0.7rem;
}

.card-head h2 { font-size: 0.98rem; color: var(--secondary); }
.card-head .count-pill {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
}

.grid-kpi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

.grid-widgets {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  align-items: start;
}

.kpi-label { color: var(--muted); font-size: 0.82rem; font-weight: 500; }
.kpi-value { font-size: 1.55rem; font-weight: 800; margin-block: 0.15rem; }
.kpi-compare { display: flex; gap: 0.7rem; font-size: 0.78rem; flex-wrap: wrap; }

.delta-up { color: var(--success); font-weight: 700; }
.delta-down { color: var(--danger); font-weight: 700; }
.delta-flat { color: var(--muted); font-weight: 700; }

/* ---------- Tables & rows ---------- */

.table-wrap { overflow-x: auto; }

table.simple {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

table.simple th {
  text-align: start;
  color: var(--muted);
  font-weight: 500;
  font-size: 0.78rem;
  padding: 0.35rem 0.5rem;
  border-block-end: 1px solid var(--divider);
}

table.simple td {
  padding: 0.45rem 0.5rem;
  border-block-end: 1px solid var(--divider);
}

table.simple tr:last-child td { border-block-end: none; }

.num { font-variant-numeric: tabular-nums; white-space: nowrap; }

.row-list { display: flex; flex-direction: column; }

.row-item {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-block: 0.5rem;
  border-block-end: 1px solid var(--divider);
  font-size: 0.88rem;
}

.row-item:last-child { border-block-end: none; }

.row-item .grow { flex: 1; min-inline-size: 0; }
.row-item .title { font-weight: 700; }
.row-item .sub { color: var(--muted); font-size: 0.78rem; }

.pill {
  border-radius: 999px;
  padding: 0.08rem 0.6rem;
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
}

.pill-success { color: var(--success); background: var(--success-soft); }
.pill-danger { color: var(--danger); background: var(--danger-soft); }
.pill-warn { color: var(--warn); background: var(--warn-soft); }
.pill-muted { color: var(--muted); background: var(--divider); }

.offline-row { opacity: 0.55; }

/* ---------- Bars (sales by branch) ---------- */

.bar-track {
  block-size: 8px;
  border-radius: 999px;
  background: var(--divider);
  overflow: hidden;
}

.bar-fill {
  block-size: 100%;
  border-radius: 999px;
  background: var(--accent);
}

/* ---------- Empty & locked states ---------- */

.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 1.6rem 1rem;
  font-size: 0.88rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  align-items: center;
}

.empty-state .glyph { font-size: 1.6rem; }

.locked-card { position: relative; }

.locked-overlay {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.2rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
}

/* ---------- Setup checklist ---------- */

.check-item { display: flex; align-items: center; gap: 0.55rem; padding-block: 0.32rem; font-size: 0.88rem; }
.check-done { color: var(--muted); text-decoration: line-through; }
.check-mark { color: var(--success); font-weight: 800; }
.check-todo-mark { color: var(--border); font-weight: 800; }

.progress-track { block-size: 8px; border-radius: 999px; background: var(--divider); overflow: hidden; margin-block: 0.5rem; }
.progress-fill { block-size: 100%; background: var(--success); border-radius: 999px; }

/* ---------- Responsive ---------- */

@media (max-width: 860px) {
  /* Rows stated explicitly. The shell is `min-height: 100vh`, and a grid with auto rows stretches
     them to fill it — so a folded sidebar with nothing but a brand and a button was still handed a
     share of the viewport, and the page content started a quarter of the way down the screen. */
  .shell {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }

  /* The sidebar used to become a horizontally scrolling strip of 35 links, which could show no
     section headings at all — a row has no room for them — and so lost on a phone exactly the
     structure the sections add. It is a normal vertical menu now, folded behind the button in
     the header, so the page content still starts at the top of the screen when it is shut. */
  .sidebar {
    border-inline-end: none;
    border-block-end: 1px solid var(--border);
    padding-block: 0.5rem;
  }

  .brand { padding-block-end: 0.35rem; }
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-button);
    background: var(--surface);
    font: inherit;
    font-weight: 600;
    color: var(--secondary);
    cursor: pointer;
  }

  .nav-sections { display: block; }
  .sidebar:not(.nav-open) .nav-sections { display: none; }
}

/* ---------- Forms & alerts ---------- */

.input {
  font-family: var(--font);
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-button);
  padding: 0.55rem 0.8rem;
  inline-size: 100%;
}

.input:focus, .select:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
.input.invalid { border-color: var(--danger); }

.field-error { color: var(--danger); font-size: 0.8rem; }

.alert {
  border-radius: var(--radius-button);
  padding: 0.6rem 0.9rem;
  font-size: 0.88rem;
  border: 1px solid transparent;
}

.alert-danger { color: var(--danger); background: var(--danger-soft); border-color: var(--danger); }
.alert-success { color: var(--success); background: var(--success-soft); border-color: var(--success); }
.alert-warn { color: var(--warn); background: var(--warn-soft); border-color: var(--warn); }

.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn-block { inline-size: 100%; justify-content: center; }
.btn-small { font-size: 0.8rem; padding: 0.25rem 0.6rem; }
.btn-danger { color: var(--danger); border-color: var(--danger); background: var(--danger-soft); }
.inline-form { display: inline; margin: 0; }

/* ---------- Auth (sign-in) ---------- */

.auth-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
}

.auth-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 1.6rem 1.5rem;
  inline-size: min(100%, 400px);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.auth-card .brand { padding-inline: 0; }
.auth-card h1 { font-size: 1.3rem; }
.auth-form { display: flex; flex-direction: column; gap: 0.4rem; }
.auth-form label { font-size: 0.85rem; color: var(--secondary); font-weight: 500; margin-block-start: 0.4rem; }
.auth-form .btn { margin-block-start: 0.8rem; }

.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--muted);
  font-size: 0.8rem;
}

.auth-divider::before, .auth-divider::after { content: ""; flex: 1; border-block-start: 1px solid var(--divider); }
.auth-hint { margin: 0; text-align: center; }
.google-mark { font-weight: 800; color: var(--accent); }
.lang-link { align-self: center; font-size: 0.85rem; }

/* ---------- List toolbar, sort, pager ---------- */

.toolbar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-block-end: 0.8rem;
}

.toolbar-search { inline-size: min(100%, 260px); }
.toolbar .spacer { flex: 1; }

.sort-btn {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  text-align: start;
}

.column-chooser { position: relative; }
.column-chooser summary { list-style: none; }
.column-chooser summary::-webkit-details-marker { display: none; }

.column-menu {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: calc(100% + 0.3rem);
  z-index: 5;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-button);
  padding: 0.5rem 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-inline-size: 180px;
  font-size: 0.85rem;
  box-shadow: 0 8px 24px rgba(51, 41, 31, 0.12);
}

.column-menu label { display: flex; align-items: center; gap: 0.45rem; }

table.registers td.actions { white-space: nowrap; }
table.registers td.actions .btn + .btn { margin-inline-start: 0.4rem; }
tr.alert-row td { background: var(--danger-soft); }

.pager {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-block-start: 0.8rem;
}

.pager .spacer { flex: 1; }

/* ---------- Modal ---------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(51, 41, 31, 0.45);
  display: grid;
  place-items: center;
  padding: 1rem;
  z-index: 20;
}

.modal {
  background: var(--surface);
  border-radius: var(--radius-card);
  padding: 1.3rem 1.4rem;
  inline-size: min(100%, 440px);
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.modal h2 { font-size: 1.05rem; }
.modal p { margin: 0; font-size: 0.9rem; }
.modal-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-block-start: 0.4rem; }

.pairing-code {
  font-size: 2.2rem;
  font-weight: 800;
  letter-spacing: 0.35em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  padding: 0.6rem;
  border-radius: var(--radius-button);
  background: var(--accent-soft);
  color: var(--accent);
}

/* ---------- Public surfaces (landing / pricing / sign-up) ----------
   Signed-out chrome. Logical properties only — the whole page mirrors in RTL with no
   direction-specific rules (i18n-rtl.md). */

.public-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.public-bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 1.4rem;
  border-block-end: 1px solid var(--border);
  background: var(--surface);
  position: sticky;
  inset-block-start: 0;
  z-index: 10;
  flex-wrap: wrap;
}

.public-bar .brand { padding: 0; font-size: 1.05rem; }

.public-nav { display: flex; gap: 1rem; margin-inline-start: 0.8rem; }
.public-nav a { color: var(--secondary); font-weight: 500; font-size: 0.9rem; }
.public-nav a:hover { color: var(--accent); }

.public-main {
  flex: 1;
  inline-size: min(100%, 1080px);
  margin-inline: auto;
  padding: 2.4rem 1.4rem 3rem;
}

.public-footer {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 1rem 1.4rem;
  border-block-start: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.85rem;
  background: var(--surface);
}

/* ---------- Hero ---------- */

.hero { text-align: center; padding-block: 1.5rem 2.5rem; }
.hero.narrow { inline-size: min(100%, 560px); margin-inline: auto; }

.hero .eyebrow {
  margin: 0 0 0.6rem;
  color: var(--accent);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
}

.hero h1 { font-size: clamp(1.7rem, 4vw, 2.6rem); line-height: 1.25; }

.hero-sub {
  margin: 0.8rem auto 0;
  max-inline-size: 62ch;
  color: var(--secondary);
  font-size: 1.02rem;
}

.hero-cta {
  display: flex;
  gap: 0.6rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-block: 1.4rem 0.7rem;
}

.btn-lg { padding: 0.6rem 1.3rem; font-size: 0.98rem; }

.notice { text-align: start; margin-block-start: 1.4rem; border-inline-start: 4px solid var(--warn); }
.notice p { margin: 0 0 0.4rem; }
.notice p:last-child { margin-block-end: 0; color: var(--secondary); }

/* ---------- Sections ---------- */

.section { padding-block: 2.4rem; scroll-margin-block-start: 4.5rem; }
.section > h2 { font-size: 1.5rem; text-align: center; }
.section-sub {
  margin: 0.6rem auto 1.8rem;
  max-inline-size: 66ch;
  text-align: center;
  color: var(--muted);
}
.closing { text-align: center; }

/* ---------- Pros grid ---------- */

.pros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1rem;
}

.pro-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 1.1rem 1.2rem;
}

.pro-glyph {
  display: grid;
  place-items: center;
  inline-size: 34px;
  block-size: 34px;
  border-radius: 10px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 1rem;
  font-weight: 800;
  margin-block-end: 0.6rem;
}

.pro-card h3 { font-size: 1rem; margin-block-end: 0.35rem; }
.pro-card p { margin: 0; color: var(--secondary); font-size: 0.9rem; }

/* ---------- Plan cards ---------- */

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 1rem;
  align-items: stretch;
}

.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 1.2rem 1.1rem;
}

.plan-card.featured { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.plan-flag {
  position: absolute;
  inset-block-start: -0.7rem;
  inset-inline-start: 1rem;
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  padding: 0.1rem 0.6rem;
  font-size: 0.72rem;
  font-weight: 700;
}

.plan-card h3 { font-size: 1.05rem; }

.plan-price { margin: 0; display: flex; align-items: baseline; gap: 0.3rem; flex-wrap: wrap; }
.plan-price .amount { font-size: 1.9rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.plan-price .per, .plan-from { color: var(--muted); font-size: 0.85rem; }
.plan-price-alt { margin: -0.2rem 0 0; color: var(--muted); font-size: 0.82rem; }
.plan-limits { margin: 0; color: var(--secondary); font-size: 0.86rem; }

.plan-lines { list-style: none; margin: 0.3rem 0 0.6rem; padding: 0; display: grid; gap: 0.35rem; flex: 1; }
.plan-lines .line { display: flex; gap: 0.45rem; align-items: flex-start; font-size: 0.86rem; }
.plan-lines .mark { font-size: 0.8rem; line-height: 1.5; }
.plan-lines .yes .mark { color: var(--success); }
.plan-lines .no { color: var(--muted); }
.plan-lines .no .mark { color: var(--muted); }
.plan-lines .detail .mark { color: var(--accent); }

/* ---------- Add-ons ---------- */

.addons { margin-block-start: 1.2rem; }
.addons h3 { font-size: 1rem; margin-block-end: 0.6rem; }
.addons ul { list-style: none; margin: 0 0 0.7rem; padding: 0; display: grid; gap: 0.35rem; }
.addons li {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  font-size: 0.9rem;
  border-block-end: 1px solid var(--divider);
  padding-block-end: 0.35rem;
}
.addons li:last-of-type { border-block-end: 0; }
.addons .addon-price { margin-inline-start: auto; color: var(--secondary); font-weight: 700; white-space: nowrap; }

@media (max-width: 640px) {
  .public-nav { display: none; }
  .public-main { padding-inline: 1rem; }
}

/* ---------- ON-1 sign-up wizard ----------
   Logical properties only: the stepper, the slug row and the banner all mirror in Arabic
   without a single left/right rule. */

.signup { text-align: start; }
.signup h1, .signup .hero-sub { text-align: center; }

.wizard-steps {
  list-style: none;
  margin: 1.4rem 0 1rem;
  padding: 0;
  display: flex;
  gap: 0.5rem;
  justify-content: center;
  flex-wrap: wrap;
  font-size: 0.85rem;
}

.wizard-step {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--muted);
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
}

.wizard-step .step-num {
  inline-size: 1.35rem;
  block-size: 1.35rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--divider);
  color: var(--secondary);
  font-size: 0.75rem;
  font-weight: 700;
}

.wizard-step.current { color: var(--ink); border-color: var(--accent); font-weight: 700; }
.wizard-step.current .step-num { background: var(--accent); color: #fff; }
.wizard-step.done { color: var(--success); border-color: var(--success); }
.wizard-step.done .step-num { background: var(--success-soft); color: var(--success); }

.signup-card { text-align: start; display: flex; flex-direction: column; gap: 0.85rem; }
.signup-card h2 { font-size: 1.15rem; }

.form-grid { display: grid; gap: 0.85rem; }

.field { display: flex; flex-direction: column; gap: 0.28rem; }
.field label { font-size: 0.85rem; font-weight: 700; }
.field .optional { font-weight: 400; color: var(--muted); font-size: 0.78rem; }
.field-help { margin: 0.2rem 0 0; display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; font-size: 0.82rem; }

.check-line { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.88rem; }
.check-line input { margin-block-start: 0.2rem; }

.slug-row { display: flex; align-items: stretch; gap: 0; }

.slug-prefix {
  display: flex;
  align-items: center;
  padding-inline: 0.7rem;
  border: 1px solid var(--border);
  border-inline-end: none;
  border-start-start-radius: var(--radius-button);
  border-end-start-radius: var(--radius-button);
  background: var(--divider);
  color: var(--secondary);
  font-size: 0.85rem;
  white-space: nowrap;
}

.slug-row .input {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
}

.slug-status { font-size: 0.8rem; min-block-size: 1.1em; color: var(--muted); }
.slug-status.slug-ok { color: var(--success); font-weight: 700; }
.slug-status.slug-bad { color: var(--danger); font-weight: 700; }
.slug-status.slug-pending { color: var(--muted); }

.store-url { margin: 0; font-size: 1.05rem; font-weight: 700; word-break: break-all; }

/* ---------- Tenant switcher (ON-1 account ↔ multiple tenants) ---------- */

.tenant-switcher { margin-block-start: 1rem; border-block-start: 1px solid var(--divider); padding-block-start: 0.8rem; }
.tenant-switcher h3 { font-size: 0.95rem; margin-block-end: 0.4rem; }
.tenant-switcher .row-item { gap: 0.6rem; align-items: center; }
.tenant-switcher .spacer { flex: 1; }
.tenant-switcher .who { display: flex; flex-direction: column; line-height: 1.2; min-inline-size: 0; }
.tenant-switcher .who .name { font-weight: 700; font-size: 0.9rem; }
.tenant-switcher .who .tenant { font-size: 0.75rem; color: var(--muted); word-break: break-all; }

/* ---------- Q4 subscription banner (trial → grace → lock) ---------- */

.sub-banner {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  padding: 0.6rem 1.1rem;
  font-size: 0.88rem;
  border-block-end: 1px solid var(--border);
}

.sub-banner .spacer { flex: 1; }
.sub-banner .sub-glyph { font-size: 1.05rem; }
.sub-banner .sub-text { display: flex; flex-direction: column; line-height: 1.25; min-inline-size: 0; }
.sub-banner .sub-detail { font-size: 0.8rem; opacity: 0.9; }

.sub-banner.sub-info { background: var(--accent-soft); color: var(--secondary); }
.sub-banner.sub-warning { background: var(--warn-soft); color: var(--warn); }
.sub-banner.sub-critical { background: var(--warn-soft); color: var(--danger); border-block-end-color: var(--danger); }
.sub-banner.sub-locked { background: var(--danger-soft); color: var(--danger); border-block-end-color: var(--danger); }

@media (min-width: 720px) {
  .form-grid { grid-template-columns: 1fr 1fr; }
  .form-grid .field:has(#storeName),
  .form-grid .field:has(#slug) { grid-column: 1 / -1; }
}

@media (max-width: 480px) {
  .wizard-steps { font-size: 0.78rem; }
  .sub-banner { align-items: flex-start; }
}

/* ============================================================================
   Data lists & editors — the doc 01 §7.3 list standard and §7.4 form standard.

   These classes were being used by CAT-2/CAT-3 before they were ever defined,
   so those screens rendered as unstyled tables; ORG-1/ORG-3/ORG-4 and CAT-1
   use the same vocabulary. Logical properties only — every one of these has to
   mirror in Arabic without a second rule.
   ========================================================================== */

.list-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding-block-end: 0.8rem;
  margin-block-end: 0.2rem;
  border-block-end: 1px solid var(--divider);
}

/* The search box takes the slack; the filters keep their intrinsic width. */
.list-toolbar input[type="search"] { flex: 1 1 14rem; min-inline-size: 10rem; }
.list-toolbar .btn-accent { margin-inline-start: auto; }

table.data-table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}

table.data-table th {
  text-align: start;
  color: var(--muted);
  font-weight: 500;
  font-size: 0.78rem;
  padding: 0.45rem 0.55rem;
  border-block-end: 1px solid var(--border);
  white-space: nowrap;
}

table.data-table td {
  padding: 0.55rem 0.55rem;
  border-block-end: 1px solid var(--divider);
  vertical-align: top;
}

table.data-table tr:last-child td { border-block-end: none; }
table.data-table tbody tr:hover { background: var(--accent-soft); }

/* Archived and suspended rows stay legible — greyed, never hidden: they are
   still the answer to "who rang this up last year?". */
table.data-table tr.row-archived td { color: var(--muted); }

.col-actions { text-align: end; white-space: nowrap; }
.col-actions .btn { margin-inline-start: 0.3rem; }

.cell-sub { color: var(--muted); font-size: 0.78rem; margin-block-start: 0.15rem; }
.mono { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; }

/* A button that reads as a link: the row's primary affordance without turning
   the whole row into a click target that swallows the action buttons. */
.link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
  text-align: start;
}
.link:hover { text-decoration: underline; }
.link.strong { font-weight: 600; color: var(--ink); }
.link.strong:hover { color: var(--accent); }

.checkbox {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  white-space: nowrap;
  cursor: pointer;
}
.checkbox input { accent-color: var(--accent); }

.check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.35rem 0.8rem;
  padding-block: 0.3rem;
}

.field-label {
  display: block;
  font-size: 0.8rem;
  color: var(--secondary);
  font-weight: 600;
  margin-block-end: 0.25rem;
}

/* A branch code, a permission key, an action name — short identifiers that are
   typed and read back, so they get a monospaced, bounded shape. */
.code-chip {
  display: inline-block;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.8rem;
  background: var(--divider);
  border-radius: 6px;
  padding: 0.1rem 0.4rem;
}

.pin-input {
  inline-size: 8rem;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 1.3rem;
  letter-spacing: 0.35em;
  text-align: center;
}

.modal-wide { inline-size: min(100%, 680px); }
/* The unsaved-changes guard sits above the editor it is guarding. */
.modal-top { z-index: 30; }

/* Depth in a tree, expressed as leading space rather than nested tables — a
   table per level cannot be scanned down one column. */
.tree-indent { display: inline-block; inline-size: calc(var(--depth, 0) * 1.4rem); }

.diff-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.8rem;
}

.json-block {
  margin: 0;
  max-block-size: 18rem;
  overflow: auto;
  background: var(--bg);
  border: 1px solid var(--divider);
  border-radius: 8px;
  padding: 0.6rem;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 0.76rem;
  /* Audit payloads are machine-written and can be a single very long line. */
  white-space: pre-wrap;
  word-break: break-word;
  /* jsonb is data, not prose: it reads left-to-right even on an Arabic page. */
  direction: ltr;
  text-align: start;
}

/* ---------- Settings screens (M2) ---------- */

/* A form that is a page rather than a dialog needs its own action bar. */
.form-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-block: 0.4rem 1rem;
}

.field-warn {
  display: block;
  color: var(--warn);
  font-size: 0.78rem;
  margin-block-start: 0.2rem;
}

.alert-warn { color: var(--warn); background: var(--warn-soft); }
.alert-success { color: var(--success); background: var(--success-soft); }

/* The rate history under a tax class: a row of dated chips, so "what was the rate in March"
   is answered by looking rather than by clicking. */
.sub-row td { padding-block-start: 0; border-block-end: 1px solid var(--divider); }

.rate-history {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-block-end: 0.4rem;
}

.rate-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  font-size: 0.82rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.15rem 0.5rem;
}

.rate-chip .rate-date { color: var(--muted); font-size: 0.74rem; }
.rate-current { border-color: var(--success); }
/* A rate that has not started yet is not the rate — it is a promise about one. */
.rate-scheduled { border-style: dashed; border-color: var(--warn); }

/* ---------------------------------------------------------------- ST-2 receipt designer */

/* Form beside paper. Collapses to one column on a phone — the owner persona works from one
   half the time (doc 01 §7). */
.designer {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (max-width: 900px) {
    .designer { grid-template-columns: minmax(0, 1fr); }
}

.designer-preview { position: sticky; top: 1rem; }

.color-field { display: flex; gap: .5rem; align-items: center; }
.color-swatch { inline-size: 3rem; block-size: 2.25rem; padding: 0; border: 1px solid var(--line); border-radius: .375rem; background: none; }
.color-field .input { inline-size: 8rem; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

.locked-list { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .375rem; }
.locked-list li { display: flex; align-items: center; gap: .5rem; }

.attribution { margin-block-start: 1rem; }
.pill { display: inline-block; padding: .125rem .5rem; border-radius: 999px; font-size: .8125rem; }
.pill-on { background: var(--ok-bg, #e6f4ea); color: var(--ok-fg, #17632c); }
.pill-off { background: var(--muted-bg, #eee); color: var(--muted-fg, #555); }

.tabs { display: flex; gap: .25rem; }
.tab { border: 1px solid var(--line); background: none; padding: .25rem .625rem; border-radius: .375rem; cursor: pointer; }
.tab-on { background: var(--accent, #2563eb); color: #fff; border-color: transparent; }

/* The paper. Monospace and pre-wrapped, because the preview reproduces a fixed-column printer:
   proportional type would centre and wrap differently from the register and the whole screen
   would be showing something the printer never produces. */
.paper {
    font-family: ui-monospace, SFMono-Regular, Menlo, "Courier New", monospace;
    font-size: .8125rem;
    line-height: 1.35;
    white-space: pre;
    overflow-x: auto;
    background: #fff;
    color: #111;
    border: 1px solid var(--line);
    border-radius: .375rem;
    padding: .75rem;
    margin: .5rem 0 0;
}

.paper-58 { max-inline-size: 26rem; }
.paper-80 { max-inline-size: 36rem; }

.preview-notes { display: grid; gap: .25rem; margin-block-start: .5rem; }

/* ------------------------------------------------------------------ M6 inventory (INV-1/2/5) */

/* The matrix scrolls rather than wrapping: a chain with eight branches must stay readable, and
   a wrapped column is a column nobody trusts. */
.matrix-scroll { overflow-x: auto; }
.matrix th.num, .matrix td.num { text-align: end; white-space: nowrap; }
.data-table td.num, .data-table th.num { text-align: end; }
.data-table td.strong { font-weight: 600; }

/* Negative is the one state that must be unmissable — it means the books disagree with the
   shelf. Colour alone would fail a colour-blind owner, so the row also carries a start border. */
.row-negative { background: var(--danger-bg, #fdecec); }
.row-negative > td:first-child { border-inline-start: 3px solid var(--danger-fg, #b3261e); }
.data-table td.neg { color: var(--danger-fg, #b3261e); font-weight: 600; }
.data-table td.low { color: var(--warn-fg, #8a5300); }

.cell-title { font-weight: 500; }
.cell-sub { font-size: .8125rem; color: var(--muted-fg, #666); }

.row-drill > td { background: var(--surface-2, #fafafa); }
.drill-list { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .25rem; }
.drill-list li { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }

.picker-list { list-style: none; margin: .375rem 0 0; padding: 0; display: grid; gap: .25rem; }
.picker-list li { padding: .125rem 0; }

.input-qty { inline-size: 6rem; text-align: end; }

.alert-warn { background: var(--warn-bg, #fff4e5); color: var(--warn-fg, #8a5300); }

/* ---------------------------------------------------------------- RPT-1/2/3 report screens */

.report-section { margin-block-start: 1.25rem; }
.report-section-title { font-size: 1rem; margin: 0 0 .5rem; }

/* Breakdowns sit side by side so branch / register / cashier / method read as one comparison,
   and collapse to one column on a phone (doc 01 §7 — the owner works from one half the time). */
.report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem; }

.kpi-row { display: flex; flex-wrap: wrap; gap: 1.25rem; margin-block-end: .75rem; }
.kpi { display: flex; flex-direction: column; min-inline-size: 7rem; }
.kpi-label { font-size: .8125rem; color: var(--muted-fg, #666); }
.kpi-value { font-size: 1.25rem; font-variant-numeric: tabular-nums; }
.kpi-value.strong { font-weight: 600; }
.kpi-value.neg { color: var(--danger-fg, #b3261e); }

/* The heatmap encodes intensity as opacity over the accent, and ALSO prints the transaction
   count in each cell — colour alone would leave a colour-blind owner reading nothing. */
.heatmap { display: grid; grid-template-columns: repeat(auto-fit, minmax(3rem, 1fr)); gap: .25rem; }
.heat-cell {
    display: flex; flex-direction: column; align-items: center; gap: .125rem;
    padding: .375rem .25rem; border-radius: .25rem;
    background: color-mix(in srgb, var(--accent, #2563eb) calc(var(--heat) * 100%), transparent);
    border: 1px solid var(--line);
}
.heat-hour { font-size: .75rem; font-variant-numeric: tabular-nums; }
.heat-count { font-size: .8125rem; font-weight: 600; }

.alert-info { background: var(--info-bg, #eef4ff); color: var(--info-fg, #1e40af); }

.data-table tfoot td { border-block-start: 2px solid var(--line); font-weight: 600; }

/* ------------------------------------------------------------------ M14 operator console (SA-1)
   Deliberately a different visual register from the store back office. An operator is looking at
   somebody else's business, so the chrome should never be mistakable for their own — hence the
   dark bar and the permanent warning strip rather than the usual header.

   All spacing is logical (inline-start/end, not left/right) so the area mirrors correctly in
   Arabic, like every other screen. */

.badge {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    line-height: 1.5;
    background: var(--surface-2, #eceff3);
    color: var(--secondary, #5b6472);
    white-space: nowrap;
}
.badge-success { background: #e4f5ea; color: #1c6b3a; }
.badge-info    { background: #e6eefc; color: #1f4a8f; }
.badge-warning { background: #fdf0dc; color: #8a5a10; }
.badge-danger  { background: #fbe6e6; color: #99231f; }

.operator-shell { min-block-size: 100vh; display: flex; flex-direction: column; }

.operator-bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.7rem 1.2rem;
    background: #1d2330;
    color: #f2f4f8;
}
.operator-brand { display: flex; align-items: center; gap: 0.5rem; font-weight: 600; }
.operator-nav { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.operator-nav a {
    color: #c8cfdb;
    text-decoration: none;
    padding: 0.3rem 0.7rem;
    border-radius: 6px;
}
.operator-nav a:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.operator-nav a.active { background: rgba(255, 255, 255, 0.16); color: #fff; }
.operator-identity {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-inline-start: auto;
}
.operator-identity .page-note { color: #aab3c2; }

/* Permanent, not dismissible: forgetting whose data you are looking at is the mistake this
   console is most likely to cause. */
.operator-warning {
    padding: 0.5rem 1.2rem;
    background: #fdf0dc;
    color: #8a5a10;
    font-size: 0.85rem;
    border-block-end: 1px solid #f0dcb8;
}

.operator-main { padding: 1.2rem; flex: 1; }

.op-totals { display: flex; flex-wrap: wrap; gap: 1.6rem; }
.op-stat { display: flex; flex-direction: column; gap: 0.15rem; }
.op-stat-value { font-size: 1.4rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.op-stat-label { font-size: 0.78rem; color: var(--secondary, #5b6472); }

.op-store { display: flex; flex-direction: column; gap: 0.1rem; }

.op-detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 1rem;
}
.op-detail-grid > div { display: flex; flex-direction: column; gap: 0.2rem; }

.op-actions { display: flex; flex-wrap: wrap; gap: 0.6rem; }

.op-flags { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.3rem; }
.op-flags li { display: flex; gap: 0.6rem; align-items: baseline; }

@media (max-width: 640px) {
    .operator-identity { margin-inline-start: 0; inline-size: 100%; }
    .op-totals { gap: 1rem; }
}

/* ---------------------------------------------------------------- print

   A supplier statement gets printed and handed over, so the print path is a real output, not a
   fallback. It prints the page's own DOM: same figures, same language, same direction, nothing
   that can drift away from what the screen showed. Navigation, filters and buttons are chrome and
   are dropped; the card loses its frame so the paper is not a screenshot of an app. */
@media print {
    .sidebar,
    .topbar,
    .operator-bar,
    .public-bar,
    .no-print {
        display: none !important;
    }

    .shell,
    .main,
    .page {
        display: block;
        margin: 0;
        padding: 0;
        max-inline-size: none;
    }

    .card {
        border: none;
        box-shadow: none;
        padding: 0;
        margin-block-end: 1rem;
        break-inside: auto;
    }

    /* A row split across a page break is a row an accountant reads twice. */
    .data-table tr {
        break-inside: avoid;
    }

    .data-table thead {
        display: table-header-group;
    }
}

/* ---------------------------------------------------------------- CAT-5 label sheet

   A 5 × 13 grid of A4 label stationery, drawn at the proportions of the real thing so a person
   can see the sheet they are about to feed rather than count squares in their head. Positions
   before the chosen start are drawn as already peeled off — a part-used sheet is the normal
   state of a stockroom, and getting the offset wrong wastes the whole sheet. */
.label-sheet {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 2px;
    max-inline-size: 40rem;
    padding: .5rem;
    background: var(--divider);
    border-radius: .25rem;
}

.label-cell {
    aspect-ratio: 38 / 21;
    background: var(--surface, #fff);
    border: 1px dashed var(--divider);
    padding: .125rem .25rem;
    overflow: hidden;
    font-size: .5rem;
    line-height: 1.15;
}

.label-cell.label-used {
    background: repeating-linear-gradient(
        45deg, var(--divider), var(--divider) 3px, transparent 3px, transparent 6px);
}

.label-name { font-weight: 600; }
.label-price { font-size: .625rem; font-weight: 700; }
.label-sku { color: var(--muted); }

@media print {
    .sheet-preview .label-sheet { background: none; padding: 0; }
    .sheet-preview .label-cell { border-color: transparent; }
}

/* CAT-1: the row being dragged. Dimmed rather than hidden — a row that vanishes mid-drag makes
   the list jump under the cursor and the drop lands somewhere nobody aimed at. */
.data-table tr.row-dragging { opacity: .45; }
.data-table tr[draggable="true"] { cursor: grab; }

/* NTF-1 alert centre.

   Severity is carried by a start-edge bar rather than a background wash: the row still has to be
   readable, and colour alone is not an accessible signal — the alert's own text says what it is.
   Logical properties throughout, so the bar lands on the correct edge in Arabic. */
.notification-list { list-style: none; margin: 0; padding: 0; }

.notification {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: .75rem 1rem;
    border-block-end: 1px solid var(--divider);
    border-inline-start: 3px solid transparent;
}

.notification:last-child { border-block-end: none; }

.notification.sev-info { border-inline-start-color: var(--secondary); }
.notification.sev-warning { border-inline-start-color: var(--warn, #b8860b); }
.notification.sev-critical { border-inline-start-color: var(--danger, #b3261e); }

/* Unread is weight, not colour — a shop floor screen is read at an angle in bad light. */
.notification.is-unread .cell-title { font-weight: 700; }
.notification.is-read .cell-title { font-weight: 400; }

/* A resolved alert stays visible and recedes. It is history, and "was I warned about this?" is a
   question somebody asks after the second time — hiding it would answer that question wrongly. */
.notification.is-resolved { opacity: .55; }

.notification-body { flex: 1 1 auto; min-inline-size: 0; }
.notification-actions { display: flex; gap: .75rem; flex: 0 0 auto; align-items: center; }

.checkbox { display: inline-flex; align-items: center; gap: .35rem; white-space: nowrap; }

/* ---------------------------------------------------------------- CRM (CRM-1)

   Logical properties throughout (padding-inline-start, border-inline-start), so the same
   rules lay out correctly in Arabic without a mirrored stylesheet — i18n-rtl.md: layouts are
   direction-agnostic, never hardcoded left/right. */
.plain-list { list-style: none; margin: 0; padding: 0; }
.plain-list > li {
    padding-block: .6rem;
    border-block-end: 1px solid var(--border);
}
.plain-list > li:last-child { border-block-end: 0; }

.detail-list { margin: 0; display: grid; gap: .6rem; }
.detail-list > div {
    display: grid;
    grid-template-columns: minmax(8rem, 12rem) 1fr;
    gap: .75rem;
    align-items: baseline;
}
.detail-list dt { color: var(--muted); font-size: .85rem; }
.detail-list dd { margin: 0; }

@media (max-width: 40rem) {
    /* The owner persona works from a phone half the time (doc 01 §7): the label/value pair
       stacks rather than squeezing a value into a third of a small screen. */
    .detail-list > div { grid-template-columns: 1fr; gap: .15rem; }
}

/* ---------------------------------------------------- Promotions (PRM-1 / PRM-2)

   The scope and day pickers are chip rows: a checkbox that reads as a toggle, wrapping to as
   many lines as the choices need. Logical properties so Arabic lays out without a mirrored
   stylesheet. */
.chip-row { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .3rem .7rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    cursor: pointer;
    font-size: .85rem;
    background: var(--surface, #fff);
}
.chip input { margin: 0; }
.chip-on { border-color: var(--accent); background: var(--accent-soft, #f6efe4); }
.field-wide { grid-column: 1 / -1; }
.input-narrow { inline-size: 5rem; text-align: end; }

/* ---------------------------------------------------------------- Guide (/guide)

   The in-app getting-started guide. Long-form reading rather than a list screen, so it gets a
   measure cap and generous line height — but it reuses .card, .page-head, .alert and .plain-list
   like every other screen.

   Logical properties only (padding-inline, border-inline-start, margin-block): the guide is read
   in Arabic by the launch market, and a mirrored stylesheet is not a thing this app has. */

.guide-body { max-inline-size: 46rem; }
.guide-body p { line-height: 1.65; margin-block: 0.5rem; }
.guide-crumb { margin-block: 0 1rem; font-size: 0.85rem; }

/* The contents list on /guide. Numbered by CSS counter rather than by hand so the numbers
   cannot drift out of step with GuideChapters. */
.guide-toc { list-style: none; margin: 0; padding: 0; counter-reset: guide-chapter; }
.guide-toc > li {
    counter-increment: guide-chapter;
    display: grid;
    grid-template-columns: 2rem 1fr;
    gap: 0.2rem 0.75rem;
    padding-block: 0.7rem;
    border-block-end: 1px solid var(--divider);
}
.guide-toc > li:last-child { border-block-end: 0; }
.guide-toc > li::before {
    content: counter(guide-chapter);
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    text-align: end;
    font-size: 0.85rem;
    padding-block-start: 0.1rem;
}
.guide-toc .cell-sub { grid-column: 2; }

/* A step inside a chapter: a numbered thing to go and do. */
.guide-steps { list-style: none; margin: 0; padding: 0; counter-reset: guide-step; }
.guide-steps > li {
    counter-increment: guide-step;
    position: relative;
    padding-inline-start: 2.1rem;
    padding-block: 0.55rem;
}
.guide-steps > li::before {
    content: counter(guide-step);
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0.5rem;
    inline-size: 1.5rem;
    block-size: 1.5rem;
    border-radius: 999px;
    background: var(--accent-soft, #f6efe4);
    color: var(--ink);
    font-size: 0.78rem;
    font-weight: 700;
    display: grid;
    place-items: center;
}
.guide-steps h3 { font-size: 0.95rem; margin-block-end: 0.15rem; }
.guide-steps p { margin-block: 0.15rem; }

/* The trap callout. Deliberately louder than .alert-warn's neighbours: these are the things a
   tester cannot undo once they have hit them. */
.guide-trap {
    border-inline-start: 4px solid var(--danger);
    padding-inline-start: 0.9rem;
    margin-block: 0.9rem;
}
.guide-trap h3 { font-size: 0.92rem; color: var(--danger); margin-block-end: 0.2rem; }

/* Credentials, ports and shell commands. Reuses .mono for the face and adds the isolation an
   Arabic paragraph needs: without it a bidi run reorders "http://localhost:5220" on screen and a
   tester types a URL that was never written. Pair it with dir="ltr" on the element. */
.guide-mono {
    background: var(--divider);
    border-radius: 4px;
    padding: 0.1rem 0.35rem;
    unicode-bidi: isolate;
}

.guide-pager {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: space-between;
    margin-block-start: 1.6rem;
    padding-block-start: 1rem;
    border-block-start: 1px solid var(--divider);
    max-inline-size: 46rem;
}
.guide-pager-next { margin-inline-start: auto; text-align: end; }

/* ============================================================================
   Dashboard announcement band (RPT-0) — AnnouncementSlider.razor.

   THIS IS THE FIRST MOTION IN THE APPLICATION. Everything above is static: no
   @keyframes, no transitions, no transforms. That is a deliberate character of
   the back-office and not an oversight, so the band spends exactly one
   animation — a 320ms fade-and-rise as a slide enters — and nothing else. The
   rise is vertical rather than horizontal because vertical is the one axis that
   means the same thing in Arabic and English; a slide that travels sideways has
   to know the reading direction and eventually gets it wrong.

   Layout is logical-properties-only, like the rest of the sheet. Colour comes
   entirely from the existing tokens; the band introduces no new hue.
   ========================================================================== */

.ann-band {
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  margin-block-end: 1rem;
  overflow: hidden;
  /* Only the active slide is in the DOM, so without a floor the band's height
     steps as the copy length changes between slides. */
  min-block-size: 168px;
  display: flex;
  flex-direction: column;
}

/* The band is focusable (tabindex="-1") so arrow keys reach it, but a ring
   around a whole region on click is noise; keyboard focus still shows. */
.ann-band:focus { outline: none; }
.ann-band:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.ann-slide {
  display: grid;
  grid-template-columns: 1fr minmax(0, 200px);
  gap: 1rem;
  flex: 1;
  align-items: center;
  padding: 1.15rem 1.25rem 0.9rem;
  animation: ann-enter 320ms cubic-bezier(0.32, 0.72, 0, 1) both;
}

/* Tint drives the art panel only, through currentColor on the inline SVG. The
   copy stays --ink / --muted on every slide: a band that recoloured its own
   headline per slide would read as four different components. */
.ann-tint-accent .ann-art { color: var(--accent); }
.ann-tint-success .ann-art { color: var(--success); }

.ann-copy { min-inline-size: 0; }

.ann-eyebrow {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin-block-end: 0.3rem;
}

.ann-title {
  /* Tops out at 1.6rem against the page's own 1.35rem h1. The usual advice is a
     2.5x jump from body to hero, but this band sits ON a dashboard rather than
     being one: type that large would make the release note louder than the
     day's takings, which is the wrong hierarchy for this screen. */
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  line-height: 1.25;
  margin-block-end: 0.35rem;
  text-wrap: pretty;
}

.ann-body {
  margin: 0 0 0.8rem;
  color: var(--muted);
  font-size: 0.875rem;
  max-inline-size: 58ch;
  text-wrap: pretty;
}

.ann-cta { display: inline-block; }

.ann-art {
  block-size: 100%;
  min-block-size: 108px;
  display: grid;
  place-items: stretch;
}

.ann-art svg { inline-size: 100%; block-size: 100%; display: block; }

.ann-controls {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 1.25rem 0.75rem;
  border-block-start: 1px solid var(--divider);
}

.ann-nav {
  inline-size: 28px;
  block-size: 28px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--secondary);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.ann-nav:hover:not(:disabled) { background: var(--divider); color: var(--ink); }
.ann-nav:disabled { opacity: 0.4; cursor: default; }

.ann-dots { display: flex; align-items: center; }

/* A 7px dot is far too small to hit, so the BUTTON is 24px and the dot is drawn
   inside it. The obvious version of this — a 7px button with an ::after at
   inset:-10px — was measured doing the wrong thing: the expanded areas overlap
   their neighbours, later siblings paint on top, and the right half of every
   dot silently clicks the NEXT one. Giving each button real width keeps the
   targets adjacent instead of stacked, so a click always lands where it looks. */
.ann-dot {
  inline-size: 24px;
  block-size: 24px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  border-radius: 999px;
}

.ann-dot::before {
  content: "";
  inline-size: 7px;
  block-size: 7px;
  border-radius: 999px;
  background: var(--border);
}

.ann-dot.is-current::before { background: var(--accent); }

.ann-dot:hover::before { background: var(--muted); }
.ann-dot.is-current:hover::before { background: var(--accent); }

.ann-dismiss {
  margin-inline-start: auto;
  border: none;
  background: none;
  padding: 0.25rem 0.3rem;
  color: var(--muted);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  border-radius: var(--radius-button);
}

.ann-dismiss:hover { color: var(--ink); background: var(--divider); }

@keyframes ann-enter {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* The art panel is the first thing to go: below this width the copy needs the
   whole measure, and a 90px-wide pattern is decoration nobody asked for. */
@media (max-width: 640px) {
  .ann-slide { grid-template-columns: 1fr; }
  .ann-art { display: none; }
  .ann-band { min-block-size: 0; }
}

/* Nothing in this band is conveyed by motion, so honouring the preference costs
   the design nothing. It is the only such rule in the sheet because the band is
   the only thing that moves. */
@media (prefers-reduced-motion: reduce) {
  .ann-slide { animation: none; }
}
