:root {
  /* Same token system as the liftlog / ARMC app fleet. */
  --mono: ui-monospace, Consolas, "DejaVu Sans Mono", "Liberation Mono", "Courier New", monospace;
  --bg: #f4f5f7;
  --panel: #ffffff;
  --ink: #16202c;
  --muted: #4a535d;
  --line: #c4ccd6;
  --accent: #234f8e;
  --ready: #1d6b3f;
  --warn: #8a6100;
  --error: #b3261e;
  /* Channel identity — one hue per sales channel, used everywhere a channel is
     named (chips, table rows, chart series) so the eye learns it once. */
  --etsy: #d5641c;
  --shopify: #4a7f3f;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--mono);
  background: var(--bg);
  color: var(--ink);
}
button, input, select, textarea { font-family: inherit; }

/* Top bar / nav */
.topbar {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  background: var(--accent);
  color: #fff;
  padding: env(safe-area-inset-top, 0px) 1.25rem 0;
  height: calc(48px + env(safe-area-inset-top, 0px));
}
.brand { font-weight: 700; color: #fff; text-decoration: none; letter-spacing: .05em; white-space: nowrap; }
.mainnav { display: flex; gap: .25rem; flex-wrap: wrap; }
.mainnav a {
  color: #dce6f4; text-decoration: none; padding: .35rem .6rem;
  border-radius: 4px; font-size: .9rem; white-space: nowrap;
}
.mainnav a:hover { background: rgba(255,255,255,.15); color: #fff; }
.mainnav a.active { background: rgba(255,255,255,.22); color: #fff; }
.whoami { margin-left: auto; display: flex; align-items: center; gap: .6rem; font-size: .8rem; color: #dce6f4; }
.whoami form { margin: 0; }
.whoami button {
  background: rgba(255,255,255,.15); color: #fff; border: 0;
  border-radius: 4px; padding: .25rem .5rem; font-size: .75rem; cursor: pointer;
}
.whoami button:hover { background: rgba(255,255,255,.28); }

.content { max-width: none; margin: 0; padding: 1rem 2rem; }
h1 { font-size: 1.4rem; margin: 0 0 .25rem; }
.lede { color: var(--muted); margin-top: 0; }
code { background: #eceff3; padding: .1rem .3rem; border-radius: 3px; font-size: .85em; }

.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 8px; padding: 1rem 1.25rem; margin: 1rem 0;
}
.panel h2 { font-size: 1.05rem; margin: 0 0 .75rem; display: flex; align-items: center; gap: .5rem; }
.badge { background: var(--accent); color: #fff; font-size: .8rem; border-radius: 10px; padding: .05rem .55rem; }
.error { color: var(--error); font-size: .85rem; }
.note { color: var(--muted); font-size: .8rem; margin: 0 0 .5rem; }
.table-wrap { overflow-x: auto; }

/* Buttons + fields */
.btn-primary {
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  border-radius: 6px; padding: .5rem 1.1rem; font-weight: 700; font-size: .9rem; cursor: pointer;
}
.btn-primary:hover { filter: brightness(1.07); }
.fld { display: block; color: var(--muted); font-size: .85rem; }
.fld input {
  display: block; width: 100%; margin-top: .2rem;
  border: 1px solid var(--line); border-radius: 6px; padding: .45rem .6rem;
  font-size: .9rem; color: var(--ink); background: #fff;
}

/* Tables */
table.grid { width: 100%; border-collapse: collapse; font-size: .82rem; }
table.grid th, table.grid td {
  border-bottom: 1px solid var(--line); padding: .4rem .6rem; text-align: left;
  white-space: nowrap;
}
table.grid th { color: var(--muted); font-weight: 700; font-size: .75rem; text-transform: uppercase; letter-spacing: .04em; }
table.grid td.num, table.grid th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.grid tbody tr:hover { background: #f7f9fb; }

/* Channel chips — the one place the channel palette is defined for text */
.chip {
  display: inline-block; border-radius: 10px; padding: .05rem .5rem;
  font-size: .72rem; font-weight: 700; color: #fff; letter-spacing: .03em;
}
.chip.etsy { background: var(--etsy); }
.chip.shopify { background: var(--shopify); }

/* Sync health — a dashboard that quietly stops updating is worse than one
   that's visibly broken, so staleness is stated, not implied. */
.sync-state { display: flex; gap: 1.5rem; flex-wrap: wrap; font-size: .8rem; }
.sync-state .ok { color: var(--ready); }
.sync-state .stale { color: var(--warn); }
.sync-state .failed { color: var(--error); }

.footer {
  max-width: none; margin: .4rem 0 0;
  padding: .3rem 1.5rem calc(1.25rem + env(safe-area-inset-bottom, 0px));
  display: flex; justify-content: space-between; color: var(--muted); font-size: .8rem;
}
.footer .version {
  background: var(--accent); color: #fff; border-radius: 4px;
  padding: .05rem .4rem; font-size: .72rem; margin-left: .3rem;
}

/* Auth pages */
.auth-box { max-width: 22rem; margin: 3rem auto; }

/* ---- Dashboard ---- */
.filterbar { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-bottom: .25rem; }
.rangebtn {
  border: 1px solid var(--line); border-radius: 6px; padding: .2rem .55rem;
  font-size: .8rem; color: var(--muted); text-decoration: none; background: var(--panel);
}
.rangebtn:hover { border-color: var(--accent); color: var(--accent); }
.rangebtn.active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 700; }

/* Stat tiles: the value is the loudest thing; label and delta stay recessive.
   Numbers are tabular so the eye can compare them down a column. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 1rem; margin: 1rem 0; }
.tile {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: .85rem 1rem; display: flex; flex-direction: column; gap: .2rem;
}
.tile-label { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; }
.tile-value { font-size: 1.7rem; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.15; }
.tile-foot { color: var(--muted); font-size: .74rem; }
/* Direction is stated by the sign in the text too — never by color alone. */
.delta { font-weight: 700; }
.delta.up { color: var(--ready); }
.delta.down { color: var(--error); }
.delta.muted { color: var(--muted); }

.legend { display: flex; gap: 1rem; margin-bottom: .6rem; font-size: .78rem; color: var(--muted); }
.legend-item { display: flex; align-items: center; gap: .35rem; }
.swatch { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.swatch.etsy { background: var(--etsy); }
.swatch.shopify { background: var(--shopify); }

/* Stacked bars, hand-rolled: one column per day, segments stacked bottom-up.
   column-reverse puts the first channel at the bottom, so :last-child is the
   visual top and takes the rounded cap. The 2px gap is the surface showing
   through between segments — it's what keeps two fills from reading as one. */
.chart { display: flex; align-items: flex-end; gap: 2px; height: 190px; }
.chart .col {
  flex: 1; min-width: 3px; height: 100%;
  display: flex; flex-direction: column-reverse; gap: 2px;
  justify-content: flex-start; cursor: crosshair;
}
.chart .seg { display: block; width: 100%; min-height: 2px; border-radius: 0; }
.chart .seg:last-child { border-radius: 4px 4px 0 0; }
.chart .seg.etsy { background: var(--etsy); }
.chart .seg.shopify { background: var(--shopify); }
.chart .col.hot { background: rgba(35, 79, 142, .07); }
.chart .col.hot .seg { filter: brightness(1.12); }
.chart-axis {
  display: flex; justify-content: space-between; margin-top: .4rem;
  color: var(--muted); font-size: .72rem; white-space: pre;
}

.tooltip {
  position: absolute; z-index: 20; pointer-events: none;
  background: var(--ink); color: #fff; border-radius: 6px;
  padding: .4rem .6rem; font-size: .76rem; line-height: 1.4;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
.tooltip .tip-detail { color: #b9c4d0; }

/* ---- Audit ---- */
.act {
  display: inline-block; border-radius: 4px; padding: .05rem .4rem;
  font-size: .72rem; font-weight: 700; background: #e6eaef; color: var(--muted);
}
.act-insert, .act-login, .act-enroll { background: #dcefe2; color: var(--ready); }
.act-update { background: #e3ebf6; color: var(--accent); }
.act-delete { background: #f7dedc; color: var(--error); }
/* A failed sign-in or a wrong passphrase is the one thing in here you'd want to
   spot from across the room — it doesn't get to look like everything else. */
.act-login_failed, .act-enroll_failed { background: var(--error); color: #fff; }
.row-alert { background: #fdf2f1; }
.row-alert:hover { background: #fbe9e7 !important; }
.muted-cell { color: var(--muted); }

.cols2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.cols2 .panel { margin: 1rem 0 0; }
@media (max-width: 760px) {
  .cols2 { grid-template-columns: 1fr; }
  .chart { height: 140px; }
}

@media (max-width: 760px) {
  .content { padding: .75rem .6rem; }
  .topbar { gap: .6rem; padding: env(safe-area-inset-top, 0px) .6rem 0; }
  .footer { padding: .3rem .6rem; }
}

/* ---- Open orders (the queue) ---- */
/* This panel is a to-do, not a fact — it gets an accent edge so it doesn't read
   as just another analytics card. */
.panel-open { border-left: 3px solid var(--accent); }
.panel-open h2 .badge { background: var(--error); }
/* An order waiting a week isn't the same as one from this morning. */
td.aging { color: var(--error); font-weight: 700; }

.ful {
  display: inline-block; border-radius: 4px; padding: .05rem .4rem;
  font-size: .72rem; font-weight: 700;
}
.ful-fulfilled   { background: #dcefe2; color: var(--ready); }
.ful-unfulfilled { background: #fdecc8; color: var(--warn); }
.ful-partial     { background: #fdecc8; color: var(--warn); }
.ful-cancelled   { background: #e6eaef; color: var(--muted); }

/* ---- Devices / people ---- */
.flash { border-left: 3px solid var(--accent); }
.section { font-size: 1.05rem; margin: 1.5rem 0 0; display: flex; align-items: center; gap: .5rem; }
/* The phrase is shown exactly once. It gets to shout. */
.phrase-box { border: 2px solid var(--accent); }
.phrase {
  font-size: 1.25rem; font-weight: 700; letter-spacing: .02em;
  background: #eef2f8; border-radius: 6px; padding: .7rem .8rem; margin: .4rem 0;
  word-break: break-word; user-select: all;      /* one tap selects the lot */
}
.devline { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; padding: .15rem 0; }
.devline form { margin: 0; }
.btn-danger {
  background: none; border: 1px solid var(--line); color: var(--error);
  border-radius: 6px; padding: .3rem .6rem; font-size: .78rem; cursor: pointer;
}
.btn-danger:hover { border-color: var(--error); background: #fdf2f1; }
.row-disabled { opacity: .55; }
.userform { display: flex; gap: .75rem; align-items: flex-end; flex-wrap: wrap; }
.userform .fld { flex: 1 1 10rem; }
.check { display: flex; align-items: center; gap: .4rem; font-size: .85rem; color: var(--muted); }
.panel-clear { border-left-color: var(--ready); }
.stale-warn { margin-left: auto; color: var(--warn); font-size: .78rem; font-weight: 700; }

/* ================= MOBILE =================
   This app is opened on a phone far more often than on a desktop — usually to
   answer one question: what do I have to ship? So the phone layout isn't a
   shrunken desktop; the tables that matter turn into cards, and every control is
   thumb-sized. */
@media (max-width: 760px) {
  /* Nav scrolls sideways instead of wrapping into a wall of links that pushes
     the actual content below the fold. */
  .topbar {
    height: auto; min-height: calc(48px + env(safe-area-inset-top, 0px));
    flex-wrap: wrap; padding-bottom: .35rem; gap: .4rem;
  }
  .mainnav {
    order: 3; width: 100%; flex-wrap: nowrap; overflow-x: auto;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding-bottom: .2rem;
  }
  .mainnav::-webkit-scrollbar { display: none; }
  .mainnav a { padding: .5rem .7rem; }        /* >=44px tall tap target */
  .whoami { margin-left: auto; font-size: .72rem; }

  h1 { font-size: 1.2rem; }
  .panel { padding: .8rem .7rem; border-radius: 6px; }
  .tiles { grid-template-columns: 1fr 1fr; gap: .6rem; }
  .tile-value { font-size: 1.35rem; }

  /* Row-per-card: each <tr> becomes a block, each <td> a labelled line. Needs
     data-label on the cells (see .cards usage in the templates). */
  table.cards, table.cards tbody, table.cards tr, table.cards td { display: block; width: 100%; }
  table.cards thead { display: none; }
  table.cards tr {
    border: 1px solid var(--line); border-radius: 6px;
    padding: .5rem .6rem; margin-bottom: .5rem; background: var(--panel);
  }
  table.cards td {
    border: 0; padding: .2rem 0; white-space: normal;
    display: flex; justify-content: space-between; gap: .75rem; align-items: baseline;
  }
  table.cards td::before {
    content: attr(data-label);
    color: var(--muted); font-size: .7rem; text-transform: uppercase;
    letter-spacing: .04em; flex: 0 0 auto;
  }
  table.cards td:empty, table.cards td[data-label=""]::before { display: none; }
  table.cards td.num { text-align: right; }

  /* Buttons and links get real thumb targets. */
  .btn-primary, .btn-danger { padding: .6rem 1rem; font-size: .85rem; }
  .rangebtn { padding: .45rem .7rem; }
  .filterbar { gap: .4rem; }

  /* The chart is decoration on a phone; the queue is the point. Keep it, but
     don't let it push everything else off-screen. */
  .chart { height: 110px; }
  .chart-axis { font-size: .65rem; }
  .userform { flex-direction: column; align-items: stretch; }
  .userform .btn-primary { width: 100%; }
  .phrase { font-size: 1.05rem; }
}
