/*
  The Admin Panel's own palette.

  Unlike the Mini App, there is no host to inherit a theme from — so this one is
  defined, and defined in both schemes: an operator looking at a maintenance
  alert at three in the morning should not be handed a white screen.
  `prefers-color-scheme` decides, and nothing else does: an admin surface with a
  theme toggle is a preference to store, sync and get wrong.

  Layout is one breakpoint. Below it the navigation is a bar along the bottom
  where a thumb reaches; above it, a rail down the side. Two layouts, not five:
  every extra breakpoint is a width nobody tests.
*/

:root {
  color-scheme: light dark;

  --bg: #faf6f5;
  --surface: #ffffff;
  --surface-2: #f3e9ec;
  --border: #e7d9df;
  --text: #281f25;
  --muted: #75636c;
  --accent: #b83d50;
  --accent-text: #ffffff;
  --ok: #1f9d55;
  --warn: #c98a12;
  --bad: #d0342c;

  --radius: 16px;
  --gap: 20px;
  --rail: 232px;
  --bar: 60px;

  /*
    Depth, not decoration. A shadow with no offset is a halo; these carry a
    downward offset and a soft blur, so a card reads as sitting above the page
    rather than glowing on it.
  */
  --lift: 0 1px 2px rgb(16 20 28 / 6%), 0 2px 8px rgb(16 20 28 / 4%);
  --lift-2: 0 2px 4px rgb(16 20 28 / 8%), 0 8px 24px rgb(16 20 28 / 8%);

  /*
    One duration and one curve for the whole surface. An operator is in a task
    and should not wait for choreography; everything here is fast enough to
    read as response rather than as animation.
  */
  --fast: 120ms;
  --base: 180ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #131216;
    --surface: #201c22;
    --surface-2: #2c252d;
    --border: #4b3945;
    --text: #e8eaed;
    --muted: #b8adb1;
    --accent: #ee8c92;
    --accent-text: #281317;
    --ok: #3ec46d;
    --warn: #e0a53a;
    --bad: #ef5350;

    /*
      Darker and larger in the dark scheme. The light-scheme shadow is invisible
      on a dark ground, which is how dark themes end up flat.
    */
    --lift: 0 1px 2px rgb(0 0 0 / 40%), 0 2px 8px rgb(0 0 0 / 24%);
    --lift-2: 0 2px 4px rgb(0 0 0 / 48%), 0 8px 24px rgb(0 0 0 / 32%);
  }
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Inter, sans-serif;
  -webkit-font-smoothing: antialiased;
}

input, select, textarea { min-height: 44px; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
h1 { text-wrap: balance; letter-spacing: -.025em; }
.main { overflow-wrap: anywhere; }
@media (max-width: 860px) { input, select, textarea { font-size: 16px !important; } }
@media (prefers-reduced-motion: no-preference) {
  @keyframes panel-arrive { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

/*
  The parts nobody draws still belong to the design: the selection, the caret,
  the scrollbar, the checkbox tick. Left alone they ship the browser's defaults,
  which belong to no palette — and on a dark scheme a default scrollbar is a
  bright stripe down the side of the page.
*/
::selection {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--text);
}

html {
  scrollbar-color: var(--border) transparent;
  scrollbar-width: thin;
  accent-color: var(--accent);
  caret-color: var(--accent);
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border: 3px solid var(--bg);
  border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--muted);
}

a {
  color: var(--accent);
  text-underline-offset: 3px;
}

/*
  Every figure in this panel is a quantity somebody compares down a column.
  Proportional digits make that comparison worse for no gain.
*/
table,
.tile__value,
.row__value,
.nav__badge,
time,
[data-numeric] {
  font-variant-numeric: tabular-nums;
}

/*
   operator may have motion turned off at the system level, and this
  surface has nothing whose meaning depends on movement.
*/
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

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

.shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: var(--rail) 1fr;
}

.rail {
  background: var(--surface);
  border-right: 1px solid var(--border);
  padding: var(--gap);
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.rail__brand {
  font-weight: 700;
  letter-spacing: 0.06em;
  font-size: 13px;
  color: var(--muted);
  padding: 4px 10px 14px;
}

.rail__who {
  margin-top: auto;
  padding: 12px 10px 0;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 12px;
}

.nav {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  color: var(--text);
}

.nav {
  transition:
    background var(--fast) var(--ease),
    color var(--fast) var(--ease);
}

.nav:hover {
  background: var(--surface-2);
}

.nav:active {
  /* A press the finger can feel, not a bounce it has to wait for. */
  transform: translateY(0.5px);
}

.nav[aria-current="page"] {
  background: var(--accent);
  color: var(--accent-text);
}

.nav__badge {
  margin-left: auto;
  background: var(--bad);
  color: #fff;
  border-radius: 999px;
  padding: 1px 7px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.main {
  padding: calc(var(--gap) * 1.5);
  max-width: 1180px;
  width: 100%;
}

@media (max-width: 860px) {
  .shell {
    grid-template-columns: 1fr;
  }

  .rail {
    position: fixed;
    inset: auto 0 0 0;
    height: auto;
    flex-direction: row;
    border-right: 0;
    border-top: 1px solid var(--border);
    padding: 6px;
    gap: 2px;
    z-index: 20;
    /* The home indicator on a phone sits under the last few pixels. */
    padding-bottom: calc(6px + env(safe-area-inset-bottom));
  }

  .rail__brand,
  .rail__who {
    display: none;
  }

  .nav {
    flex: 1;
    width: auto;
    min-width: 0;
    overflow-wrap: anywhere;
    flex-direction: column;
    gap: 2px;
    font-size: 11px;
    padding: 6px 2px;
    justify-content: center;
    text-align: center;
  }

  .nav__badge {
    margin: 0;
    position: absolute;
    transform: translate(14px, -10px);
  }

  .main {
    padding: var(--gap);
    padding-bottom: calc(var(--bar) + var(--gap) * 2);
  }
}

/* --- headings ------------------------------------------------------------ */

h1 {
  font-size: 22px;
  line-height: 1.25;
  letter-spacing: -0.011em;
  text-wrap: balance;
  margin: 0 0 20px;
}

h2 {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 28px 0 10px;
}

.muted {
  color: var(--muted);
}

.page-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.page-heading h1 { margin-bottom: 6px; }
.page-heading .eyebrow { color: var(--muted); margin: 0 0 4px; }
.page-heading .muted { margin: 0; max-width: 72ch; }
.pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0 24px;
}
.subtabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  margin: 0 0 20px;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--border);
}
.subtab {
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--muted);
  padding: 10px 12px;
  min-height: 42px;
  cursor: pointer;
  white-space: nowrap;
}
.subtab.is-active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 650; }

/* --- tiles --------------------------------------------------------------- */

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
}

.tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: var(--lift);
}

.tile__value {
  font-size: 26px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.tile__label {
  color: var(--muted);
  font-size: 12px;
  margin-top: 2px;
}

.tile--warn .tile__value {
  color: var(--warn);
}

.tile--bad .tile__value {
  color: var(--bad);
}

/* --- cards and tables ---------------------------------------------------- */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: var(--gap);
  box-shadow: var(--lift);
}

.card__head {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
}

.row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
  width: 100%;
  background: none;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  text-align: left;
  cursor: default;
}

button.row {
  cursor: pointer;
}

button.row {
  transition: background var(--fast) var(--ease);
}

button.row:hover {
  background: var(--surface-2);
}

button.row:active {
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-2));
}

.row:last-child {
  border-bottom: 0;
}

.row__body {
  flex: 1;
  min-width: 0;
}

.row__title {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.row__meta {
  display: block;
  color: var(--muted);
  font-size: 12px;
}

.row__value {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/*
  A wide table scrolls inside its own box. The page never scrolls sideways —
  a horizontal scrollbar on the whole document hides the navigation on a phone.
*/
.scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* --- controls ------------------------------------------------------------ */

.field {
  display: block;
  margin-bottom: 12px;
}

.field__label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 4px;
}

input[type="text"],
input[type="password"],
input[type="number"],
input[type="search"],
select,
textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}

input[type="text"],
input[type="password"],
input[type="number"],
input[type="search"],
select,
textarea {
  transition:
    border-color var(--fast) var(--ease),
    background var(--fast) var(--ease);
}

input:hover:not(:disabled),
select:hover:not(:disabled),
textarea:hover:not(:disabled) {
  border-color: var(--muted);
}

input:disabled,
select:disabled,
textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/*
  The error state is on the element the assistive technology already reads, so
  the colour and the announcement cannot drift apart.
*/
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"] {
  border-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 6%, var(--bg));
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible {
  /* Two rings: the accent reads on the light scheme, the inner halo keeps it
     visible where the accent sits against a surface of its own colour. */
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 8px;
}

.btn {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  padding: 9px 14px;
  cursor: pointer;
  transition:
    background var(--fast) var(--ease),
    border-color var(--fast) var(--ease),
    box-shadow var(--fast) var(--ease),
    transform var(--fast) var(--ease);
}

.btn:hover:not([disabled]) {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--surface-2));
}

.btn:active:not([disabled]) {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
  box-shadow: var(--lift);
}

.btn--primary:hover:not([disabled]) {
  background: color-mix(in srgb, var(--accent) 88%, var(--text));
  border-color: color-mix(in srgb, var(--accent) 88%, var(--text));
}

.btn--danger {
  border-color: var(--bad);
  color: var(--bad);
}

.btn--danger:hover:not([disabled]) {
  background: color-mix(in srgb, var(--bad) 10%, var(--surface-2));
  border-color: var(--bad);
}

.btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/*
  A button that is doing something says so where it was pressed. Sending the
  operator to a bar at the top of the page for feedback on a button at the
  bottom is how a form gets submitted twice.
*/
.btn[aria-busy="true"] {
  color: transparent;
  pointer-events: none;
  position: relative;
}

.btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid currentcolor;
  border-color: var(--muted) transparent var(--muted) transparent;
  animation: spin 620ms linear infinite;
}

.btn--primary[aria-busy="true"]::after {
  border-color: var(--accent-text) transparent var(--accent-text) transparent;
}

@keyframes spin {
  to {
    transform: rotate(1turn);
  }
}

/*
  A form inside a card. Fields flow side by side when there is room and stack
  when there is not; the button always ends up on its own row, because a submit
  button wedged between two inputs is one people press by accident.
*/
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 8px 12px;
  padding: 12px 16px;
}

.actions .field {
  flex: 1 1 220px;
  margin-bottom: 0;
  min-width: 0;
}

.actions > .btn,
.actions > button[type="submit"] {
  flex: 1 0 100%;
  margin-top: 4px;
}

@media (min-width: 861px) {
  .actions > .btn,
  .actions > button[type="submit"] {
    /* Room for it beside the fields on a wide screen, still on its own line
       when they fill the row. */
    flex: 0 0 auto;
    margin-top: 0;
  }
}

@media (max-width: 860px) {
  .actions .field {
    flex-basis: 100%;
  }
}

/* --- status -------------------------------------------------------------- */

.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 12px;
  background: var(--surface-2);
  color: var(--muted);
  white-space: nowrap;
}

.pill--ok {
  background: color-mix(in srgb, var(--ok) 16%, transparent);
  color: var(--ok);
}

.pill--warn {
  background: color-mix(in srgb, var(--warn) 18%, transparent);
  color: var(--warn);
}

.pill--bad {
  background: color-mix(in srgb, var(--bad) 16%, transparent);
  color: var(--bad);
}

/* --- feedback ------------------------------------------------------------ */

/*
  A banner is tinted from its own hue rather than striped down one edge. The
  stripe is the cheap version: it colours three pixels and leaves the rest of
  the alert looking like every other card, so the severity is carried by the
  one part of the element the eye reaches last.
*/
.banner {
  border-radius: var(--radius);
  padding: 12px 16px;
  margin-bottom: var(--gap);
  border: 1px solid var(--border);
  background: var(--surface);
  box-shadow: var(--lift);
}

.banner--bad {
  border-color: color-mix(in srgb, var(--bad) 40%, var(--border));
  background: color-mix(in srgb, var(--bad) 8%, var(--surface));
  /* Tinted from the hue, never grey: grey secondary text on a coloured ground
     reads as a different element that wandered in. */
  color: color-mix(in srgb, var(--bad) 30%, var(--text));
}

.banner--warn {
  border-color: color-mix(in srgb, var(--warn) 40%, var(--border));
  background: color-mix(in srgb, var(--warn) 10%, var(--surface));
  color: color-mix(in srgb, var(--warn) 28%, var(--text));
}

.banner--ok {
  border-color: color-mix(in srgb, var(--ok) 40%, var(--border));
  background: color-mix(in srgb, var(--ok) 9%, var(--surface));
  color: color-mix(in srgb, var(--ok) 30%, var(--text));
}

/*
  An empty state teaches the surface. "No transactions." tells an operator
  nothing they did not already see; the second line says what would put
  something here.
*/
.empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--muted);
  display: grid;
  gap: 6px;
  justify-items: center;
}

.empty__title {
  color: var(--text);
  font-weight: 600;
}

.empty__hint {
  max-width: 42ch;
  text-wrap: balance;
}

/*
  Loading looks like the shape of what is coming, not like a spinner in the
  middle of an empty panel. An operator can start reading the layout before the
  data lands, and the page does not jump when it does.
*/
.skeleton {
  display: grid;
  gap: 10px;
  padding: 14px 16px;
}

.skeleton__line {
  height: 12px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    color-mix(in srgb, var(--surface-2) 55%, var(--border)) 50%,
    var(--surface-2) 100%
  );
  background-size: 200% 100%;
  animation: shimmer 1.4s var(--ease) infinite;
}

.skeleton__line--short {
  width: 40%;
}

.skeleton__line--medium {
  width: 68%;
}

@keyframes shimmer {
  from {
    background-position: 140% 0;
  }
  to {
    background-position: -40% 0;
  }
}

.progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--accent);
  transform-origin: left;
  animation: progress 1.1s ease-in-out infinite;
  z-index: 40;
}

@keyframes progress {
  0% {
    transform: scaleX(0);
    opacity: 1;
  }
  65% {
    transform: scaleX(1);
    opacity: 1;
  }
  100% {
    transform: scaleX(1);
    opacity: 0;
  }
}

/* --- sign in ------------------------------------------------------------- */

.signin {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--gap);
}

.signin__box {
  width: 100%;
  max-width: 340px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 24px;
}

.pre {
  white-space: pre-wrap;
  word-break: break-word;
  background: var(--surface-2);
  border-radius: 8px;
  padding: 10px 12px;
  margin: 0;
  font-size: 13px;
}

/* A button that reads as a link: recovery entry, and anything else that
   is a way out of a screen rather than the action the screen is for. Kept a
   real <button> — a bare <a> with no href is not reachable from a keyboard. */
.btn--link {
  background: none;
  border: none;
  color: var(--accent);
  padding: 8px 0;
  font: inherit;
  cursor: pointer;
  text-align: center;
  width: 100%;
}

.btn--link:hover {
  text-decoration: underline;
}

.signin__box hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: 18px 0;
}

/* R7: phone/tablet/desktop share the same readable component geometry. */
html { scrollbar-gutter:stable; }
body { padding-bottom:env(safe-area-inset-bottom); }
main, section, article, .panel, .client-card, .card { min-width:0; }
h1, h2, h3 { overflow-wrap:anywhere; text-wrap:balance; }
button, input, select, textarea { touch-action:manipulation; }
input, select, textarea { max-width:100%; font-size:16px; }
button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible, summary:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
.btn { min-height:44px; line-height:1.3; white-space:normal; }
.metrics { gap:12px; }
.metric { min-width:0; padding:18px; }
.metric__value { font-size:clamp(24px,4vw,36px); overflow-wrap:anywhere; }
@media (max-width:760px) {
 :root { --gap:16px; --radius:16px; }
 .panel, .card { overflow:hidden; }
 .panel__head, .page-heading { align-items:flex-start; gap:12px; flex-wrap:wrap; }
 .panel__head > div,.page-heading > div { min-width:0; flex:1 1 180px; }
 .metrics { grid-template-columns:repeat(2,minmax(0,1fr)); }
 .client-hero, .client-card { padding:18px; }
 .client-tabs { overflow:auto; flex-wrap:nowrap; }
 table { font-size:13px; }
 th,td { padding:12px 10px; }
 .toolbar { flex-wrap:wrap; }
 .toolbar input { flex:1 1 160px; min-width:0; }
}
@media (max-width:390px) { .metric { padding:14px; } }
/* Comfortable density and stable action placement from phones to desktops. */
.page-head, .client-hero { gap:16px; align-items:start; }
.page-head .btn { align-self:start; flex-shrink:0; }
.kv > *, .form-grid > *, .client-hero > * { min-width:0; }
.kv dd { overflow-wrap:anywhere; }
input[type=checkbox] { width:24px; height:24px; accent-color:var(--accent); }
input, select, textarea { min-height:44px; }
.tab { min-height:44px; white-space:nowrap; }
@media(max-width:760px) {
  .panel, .card { overflow:visible; }
  .page-head { display:flex; flex-wrap:wrap; }
  .page-head h1 { font-size:clamp(24px,6vw,32px); margin:0; }
  .actions { gap:8px; }
  .kv { grid-template-columns:minmax(0,1fr); gap:12px; }
  .form-grid { grid-template-columns:minmax(0,1fr); }
  .tabs { display:flex; overflow-x:auto; flex-wrap:nowrap; gap:6px; scrollbar-width:thin; }
}
@media(prefers-reduced-motion:reduce) { *, *::before, *::after { scroll-behavior:auto!important; animation-duration:.01ms!important; transition-duration:.01ms!important; } }
