/* BettrRepairShopr — shared styles.
   Theme: "the shop after hours" — a dark room lit by a desk lamp. Warm amber
   accent (the lamp), dark walnut/charcoal surfaces, manila folder chrome up
   top. The base rules below define layout; the big "desk theme" section at
   the bottom of this file restyles chrome (folder tabs, keycaps, desk). */

:root {
  /* room + surfaces */
  --bg: #0c0e13;
  --bg-deep: #080a0e;
  --surface: #161a23;
  --surface-2: #1c212e;
  --surface-3: #232939;
  /* warm text on dark */
  --ink: #e9e4d8;
  --muted: #93989f;
  /* lines */
  --line: #272d3c;
  --line-soft: #1f2431;
  /* lamp amber accent */
  --accent: #e8a23d;
  --accent-bright: #ffc361;
  --accent-ink: #2a1a04;
  --accent-soft: rgba(232, 162, 61, 0.14);
  --accent-glow: rgba(255, 195, 97, 0.28);
  /* status */
  --danger: #e2574f;
  --ok: #45c07d;
  --info: #7ea2ff;
  /* keycaps */
  --key: #262c3a;
  --key-hi: #323a4d;
  --key-side: #0d1017;
  --key-ink: #dfe3ea;
  /* manila folder chrome */
  --folder: #4a3f2d;
  --folder-hi: #5c4f37;
  --folder-tab: #6b5b3e;
  --folder-tab-ink: #e6d9b8;
  --paper: #f4eddc;
  --paper-ink: #2b261e;
  --radius: 10px;
  --font-mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
  /* native controls (select popups, date pickers) render dark */
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* the room: deep charcoal with a faint warm cast from the desk lamp */
  background:
    radial-gradient(1300px 700px at 18% -12%, #1a1720 0%, transparent 55%),
    radial-gradient(900px 600px at 105% 8%, #12151d 0%, transparent 60%),
    var(--bg);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
  padding-bottom: 56px; /* keep content clear of the taskbar */
}

::selection { background: rgba(232, 162, 61, 0.35); color: #fff; }

/* dark scrollbars everywhere */
* { scrollbar-width: thin; scrollbar-color: #333a4c #12151d; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: #12151d; }
::-webkit-scrollbar-thumb {
  background: #333a4c;
  border-radius: 8px;
  border: 2px solid #12151d;
}
::-webkit-scrollbar-thumb:hover { background: #454e63; }

.hidden { display: none !important; }
.muted { color: var(--muted); font-size: 13px; }

/* ---------- top bar ---------- */

.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  height: 52px;
  padding: 0 24px;
  display: flex;
  align-items: center;
}

.brand {
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.2px;
}

.brand span { color: var(--accent); }

/* ---------- dashboard ---------- */

/* ---------- top nav ---------- */

.topnav {
  display: flex;
  gap: 6px;
  margin-left: 28px;
}

.topnav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
  padding: 7px 12px;
  border-radius: 8px;
}

.topnav a:hover {
  color: var(--ink);
  background: #eef1f9;
}

.topnav a.active {
  color: var(--accent);
  background: var(--accent-soft);
  font-weight: 600;
}

/* ---------- pages ---------- */

.page {
  max-width: 1080px;
  margin: 0 auto;
  padding: 28px 24px 40px;
}

.page-narrow { max-width: 620px; }

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.page-head h1 {
  margin: 0;
  font-size: 24px;
  letter-spacing: -0.3px;
}

.dash-hero h1 {
  margin: 0 0 4px;
  font-size: 26px;
  letter-spacing: -0.3px;
}

.dash-hero p { margin: 0 0 24px; color: var(--muted); }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 14px;
}

.tile {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--radius);
  padding: 22px 16px;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}

.tile:hover:not(:disabled) {
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.10);
  transform: translateY(-1px);
}

.tile:disabled { cursor: default; opacity: 0.55; }

.tile-icon {
  font-size: 22px;
  color: var(--accent);
  line-height: 1;
}

.tile-title { font-weight: 600; font-size: 16px; }

.tile-sub { color: var(--muted); font-size: 12.5px; }

.tile-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.tile-primary .tile-icon { color: var(--accent-ink); }
.tile-primary .tile-sub { color: rgba(255, 255, 255, 0.75); }

.soon {
  align-self: flex-start;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
}

/* ---------- intake form (inside windows) ---------- */

.intake {
  max-width: 560px;
  margin: 0 auto;
  padding: 10px 14px 24px;
}

/* Drop-off form window: preview fills the top, signature card sits at the
   bottom, so the window can be sized freely without scrolling the body. */
.dropoff-form {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

.dof-preview {
  flex: 1;
  min-height: 0;
  padding: 10px 12px 0;
}

.dof-frame {
  width: 100%;
  height: 100%;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
}

.dof-sign-card {
  flex: 0 0 auto;
  margin: 10px 12px 12px;
}

.dof-sign-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

.dof-sign-row label {
  flex: 1;
  margin-bottom: 10px;
}

.dof-sign-row .btn {
  margin-bottom: 10px;
}

.dof-actions {
  margin-top: 10px;
}

.dof-actions .dof-sign {
  margin-left: auto;
}

/* ---------- intake estimate card (collapsible quote) ---------- */

.est-lines-head,
.est-line {
  display: grid;
  /* description | qty | price | taxable | amount | actions.
     The actions column is FIXED (wide enough for the ✕) so the blank
     trailing row — whose ✕ only appears once the row is filled — never
     shifts the other columns relative to the header and the rows above
     (same as the document editor's lines). */
  grid-template-columns: minmax(0, 1fr) 52px 78px 36px 64px 28px;
  gap: 6px;
  align-items: center;
}

.est-lines-head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  padding-bottom: 6px;
}

.est-lines-head .est-h-amount { text-align: right; }

.est-line { margin-bottom: 8px; }

.est-line input[type='text'],
.est-line input[type='number'] {
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13px;
}

.est-line .check { margin-bottom: 0; }

/* The description cell hosts the per-row catalog typeahead — the dropdown
   floats over what follows (same as the document editor's lines). */
.est-line-desc {
  position: relative;
  min-width: 0;
}

.est-line-desc input { width: 100%; }

.est-line-desc .results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 30;
  margin: 2px 0 0;
  max-height: 240px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* The whole row is the click target (and arrow-key target). */
.est-line-desc .result {
  cursor: pointer;
}

.est-line-desc .result:hover {
  background: rgba(255, 255, 255, 0.05);
}

/* Keyboard-highlighted row (arrow keys) — same treatment as the
   phone-parts cascade's typeahead. */
.est-line-desc .result.hi {
  background: var(--accent-soft, rgba(28, 35, 51, 0.08));
}

/* "part pending" rides under the description (inside the cell, so it never
   opens an extra grid column). */
.est-line-desc .est-pending-tag { margin-top: 2px; }

.est-search { position: relative; }

.est-search input {
  width: 100%;
  font-size: 13.5px;
}

.est-search .results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 5;
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* Suggested parts (the quick repair's scoped parts picker in the estimate). */
.est-parts input {
  width: 100%;
  font-size: 13.5px;
}

.est-parts .results {
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* Phone-parts cascade (Phone -> Part -> Color -> Quality): the guided
   picker for built-in phone labors in the intake estimate and the document
   editor. Steps sit on one row; the variant list reuses the .result rows. */
.pp-cascade .pp-steps {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.pp-cascade .pp-step {
  flex: 1 1 150px;
  min-width: 0;
}

.pp-cascade .pp-step select {
  width: 100%;
  font-size: 13.5px;
}

.pp-cascade .pp-variants {
  max-height: 260px;
  overflow-y: auto;
  margin-top: 8px;
}

.pp-cascade .pp-quality {
  max-width: 220px;
  margin-right: 8px;
  font-size: 13.5px;
}

/* The phone step is a searchable typeahead (40+ models): the input hosts a
   dropdown of matching models; the × clears the pick. */
.pp-cascade .pp-phone-step {
  position: relative;
}

.pp-cascade .pp-phone {
  width: 100%;
  font-size: 13.5px;
  padding-right: 26px;
}

.pp-cascade .pp-phone-clear {
  position: absolute;
  top: 50%;
  right: 5px;
  transform: translateY(-50%);
  width: 18px;
  height: 18px;
  padding: 0;
  line-height: 1;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 14px;
  cursor: pointer;
}

.pp-cascade .pp-phone-clear:hover {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.08);
}

.pp-cascade .pp-phone-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 30;
  margin: 2px 0 0;
  max-height: 240px;
  overflow-y: auto;
  background: var(--surface);
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

.pp-cascade .pp-phone-results .result {
  cursor: pointer;
  padding: 7px 10px;
}

.pp-cascade .pp-phone-results .result:hover {
  background: rgba(255, 255, 255, 0.05);
}

/* Keyboard-highlighted typeahead row (arrow keys). */
.pp-cascade .pp-hi,
.pp-cascade .pp-phone-results .result.pp-hi {
  background: var(--accent-soft, rgba(28, 35, 51, 0.08));
}

/* Quick repair card (intake): typeahead styled like the other pickers. */
.qr-card .qr-search {
  width: 100%;
  font-size: 13.5px;
}

.qr-card .qr-results {
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* Keyboard-highlighted quick-repair row (arrow keys). The row's Select
   button stays the click target — the highlight is the keyboard's cursor. */
.qr-card .result.hi {
  background: var(--accent-soft, rgba(28, 35, 51, 0.08));
}

/* Device-fit rows in the catalog item editor (parts). */
.cat-fit-row {
  display: flex;
  gap: 6px;
  align-items: center;
  margin-bottom: 6px;
}

.cat-fit-row select {
  flex: 0 0 110px;
}

.cat-fit-row input {
  flex: 1;
  min-width: 0;
}

.cat-fit-row .li-remove {
  flex: 0 0 auto;
}

.est-totals {
  max-width: 250px;
  margin-left: auto;
  margin-top: 8px;
}

.est-total-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  font-size: 13.5px;
}

.est-total-row.est-grand {
  border-top: 1px solid var(--line);
  margin-top: 3px;
  padding-top: 6px;
  font-size: 15px;
}

/* Pickup form window: preview fills the top, signature card sits at the
   bottom — same shape as the drop-off form window. */
.pickup-form {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
}

/* ---------- pickup window ---------- */

.pickup {
  padding: 10px 14px 20px;
}

/* Queue rows: customer | ticket | balance on one clickable line. */
.pu-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}

.pu-row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px 12px;
  cursor: pointer;
  font: inherit;
  color: inherit;
}

.pu-row:hover {
  border-color: var(--accent);
  background: rgba(232, 162, 61, 0.06);
}

.pu-row-main {
  flex: 1 1 32%;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pu-row-main .muted {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pu-row-mid {
  flex: 1 1 46%;
  min-width: 0;
  display: flex;
  gap: 6px;
  align-items: baseline;
  font-size: 13.5px;
}

.pu-row-mid span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pu-row-right {
  flex: 0 0 auto;
  text-align: right;
  font-size: 13px;
}

.pu-balance {
  color: var(--danger);
  font-weight: 600;
}

.pu-paid {
  color: var(--ok);
  font-weight: 600;
}

.pu-detail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 2px 0 10px;
}

.pu-detail-head b {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pu-detail-head .pu-status-tag {
  margin-left: auto;
  flex: 0 0 auto;
}

.pu-assets-wrap {
  margin-top: 12px;
}

.pu-assets-wrap > b {
  display: block;
  margin-bottom: 6px;
}

.pu-pay {
  margin-top: 14px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

.pu-pay > b {
  display: block;
  margin-bottom: 8px;
}

.pu-flash {
  color: var(--ok);
}

/* the pickup form's "✓ Signed" line under the template controls */
.pu-signed {
  color: var(--ok);
}

/* ---------- asset window (customer page) ---------- */

.asset-view {
  max-width: 560px;
  margin: 0 auto;
  padding: 10px 14px 20px;
}

.av-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.av-head-row .av-customer-row { margin: 0; }

.av-edit-actions { display: inline-flex; gap: 6px; }

.av-customer-row {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 10px;
}

.av-fields {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 6px 16px;
  margin-bottom: 14px;
}

.av-field {
  display: flex;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  align-items: baseline;
}

.av-field:last-child { border-bottom: 0; }

.av-label {
  flex: 0 0 110px;
  color: var(--muted);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.av-actions .av-close { margin-left: auto; }

/* ---------- ticket form: asset card (single merged section) ---------- */

.asset-selected .asset-selected-label { flex: 1; }

.asset-selected-password {
  font-size: 12px;
  color: var(--muted);
  font-weight: normal;
  margin-top: 2px;
}

.asset-selected-actions {
  display: inline-flex;
  gap: 6px;
}

.tf-current-assets { margin-bottom: 10px; }

.tf-current-asset {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 6px;
}

.tf-current-asset .li-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tf-current-asset .li-head b { flex: 1; }

/* ---------- customer page: billing balance strip ---------- */

.cd-balance-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 12px;
  background: var(--accent-soft);
  border: 1px solid rgba(232, 162, 61, 0.35);
  border-radius: 8px;
  margin-bottom: 12px;
  font-size: 14px;
}

.cd-balance-row b { font-size: 16px; }

.cd-balance-row .hint { margin-left: auto; }

.cd-balance-row .cd-balance-paid { color: var(--ok); }

/* The balance pill shares the tab row — drop its own strip margin there. */
.bill-head-row .cd-balance-row {
  margin-bottom: 0;
  margin-left: auto;
}

/* Tabs and the balance pill on one line: tabs left, balance right. */
.bill-head-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.bill-head-row .bill-tabs { margin-bottom: 0; }

/* ---------- customer page: billing tab tables (estimates/invoices/payments) ---------- */

.bill-table .ta-r { text-align: right; }

/* Row action buttons inside table cells: no list-style top margin, and
   right-aligned to line up with the money column. */
.bill-table .cd-pay-actions { margin-top: 0; justify-content: flex-end; }

/* The always-present "+" row that leads each billing table. */
.bill-add-row td { padding: 0; }
.bill-add-btn {
  appearance: none;
  font: inherit;
  font-size: 16px;
  line-height: 1.3;
  display: block;
  width: 100%;
  text-align: left;
  padding: 6px 12px 7px;
  background: transparent;
  border: none;
  color: var(--accent);
  cursor: pointer;
}

/* ---------- customer page: payment form ---------- */

.cd-pay-amount-wrap {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.cd-pay-amount-wrap input {
  flex: 1;
  min-width: 0;
}

.cd-pay-balance {
  white-space: nowrap;
  background: var(--accent-soft);
  border-color: rgba(232, 162, 61, 0.4);
}

.cd-pay-balance:hover { background: rgba(232, 162, 61, 0.24); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin-bottom: 14px;
}

.card h2 {
  margin: 0 0 12px;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
}

label {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 10px;
}

label.check {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  font-size: 14px;
}

input[type="text"], input[type="tel"], input[type="email"],
input[type="date"], input[type="number"], input[type="password"],
select, textarea {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 8px 10px;
  font: inherit;
  color: var(--ink);
  background: #12151e;
  border: 1px solid #2b3244;
  border-radius: 8px;
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.35);
  caret-color: var(--accent-bright);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.35), 0 0 0 3px rgba(232, 162, 61, 0.16);
}

input::placeholder, textarea::placeholder { color: #6b7280; }

textarea { resize: vertical; }

input[type="radio"], input[type="checkbox"] { accent-color: var(--accent); }

.radios {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.radio {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--ink);
}

.row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}

.btn {
  appearance: none;
  font: inherit;
  font-size: 14px;
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none; /* the class also styles download <a> buttons */
}

.btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }

.btn:disabled { opacity: 0.5; cursor: default; }

.btn-small { padding: 4px 10px; font-size: 13px; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

.btn-primary:hover:not(:disabled) {
  color: var(--accent-ink);
  background: #2b46b3;
  border-color: #2b46b3;
}

.hint { color: var(--muted); font-size: 13px; }

.selected-info { min-width: 0; }

.cust-new-note {
  margin: 10px 0 2px;
  color: var(--accent);
  font-style: italic;
}

.results {
  margin: 10px 0 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}

/* Create-new button under the asset picker's list */
.asset-new-btn { margin-top: 10px; }

.result {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  background: var(--surface);
}

.result + .result { border-top: 1px solid var(--line); }

.result-info { min-width: 0; }

.selected {
  margin-top: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--accent-soft);
  border: 1px solid rgba(232, 162, 61, 0.35);
  color: var(--ink);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 14px;
}

.savebar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin: 4px 0 16px;
}

/* Part form: vendor rows (which vendors supply this part, at what cost —
   a part has no cost of its own anymore). */
.cat-f-vendors {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 6px 0 4px;
}

.cat-vendor-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.cat-vendor-row label.check {
  flex: 1 1 0;
  min-width: 0;
}

.cat-f-vendor-cost {
  flex: 0 0 120px;
  width: 120px;
  padding: 4px 8px;
  font-size: 13.5px;
}

.error {
  color: var(--danger);
  font-size: 13.5px;
  flex: 1;
  text-align: right;
}

.success p { margin: 4px 0 14px; font-size: 15px; }

.success .btn-primary { display: none; }

/* ---------- in-app desktop, windows, and taskbar ---------- */

.desktop {
  position: fixed;
  top: 57px; /* below the 56px topbar + its border */
  left: 0;
  right: 0;
  bottom: 44px;
  pointer-events: none; /* clicks fall through to the page… */
  z-index: 500;
}

.taskbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: 44px;
  z-index: 100000;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  background: var(--surface);
  border-top: 1px solid var(--line);
  overflow-x: auto;
}

.taskchip {
  appearance: none;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  border: 1px solid var(--line);
  background: var(--surface);
  border-radius: 999px;
  padding: 5px 14px;
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
}

.taskchip.active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.taskchip.minimized { opacity: 0.6; }

.win {
  position: absolute;
  display: flex;
  flex-direction: column;
  pointer-events: auto; /* …but windows catch their own clicks */
  background: var(--surface);
  border: 1px solid #303848;
  border-radius: 12px;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.55),
    0 0 0 1px rgba(0, 0, 0, 0.4),
    0 0 40px rgba(232, 162, 61, 0.05);
  overflow: hidden;
}

.win.focused {
  border-color: rgba(232, 162, 61, 0.55);
  box-shadow:
    0 28px 70px rgba(0, 0, 0, 0.65),
    0 0 0 1px rgba(232, 162, 61, 0.25),
    0 0 55px rgba(232, 162, 61, 0.09);
}

.win.maximized { border-radius: 0; }

.win-titlebar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px 7px 14px;
  background: #10141c;
  border-bottom: 1px solid var(--line);
  cursor: grab;
  touch-action: none;
  user-select: none;
  flex: 0 0 auto;
}

.win-titlebar:active { cursor: grabbing; }

.win.focused .win-titlebar {
  background: linear-gradient(180deg, #f2b74e, #d68f28);
  color: var(--accent-ink);
  border-bottom-color: rgba(0, 0, 0, 0.25);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
}

.win-title {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.win-btn {
  appearance: none;
  border: none;
  background: transparent;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1;
  color: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.win-btn:hover { background: rgba(255, 255, 255, 0.10); }
.win.focused .win-btn:hover { background: rgba(0, 0, 0, 0.18); }
.win-btn.win-close:hover { background: var(--danger); color: #fff; }

.win-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  background: var(--bg);
}

.win-grip {
  position: absolute;
  right: 2px;
  bottom: 2px;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  touch-action: none;
  border-radius: 3px;
  background: repeating-linear-gradient(135deg, transparent 0 4px, #39415a 4px 6px);
}

.win.maximized .win-grip { display: none; }

/* ---------- customers list & new-customer form ---------- */

.toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.toolbar input {
  flex: 1;
  min-width: 0; /* several inputs share the row; let them compress */
  margin-top: 0;
}

.toolbar select {
  /* width:100% is the global control rule; inside this flex row the select
     gets a fixed share instead (auto basis would claim the whole row and
     squeeze the make/model inputs away). */
  flex: 0 0 170px;
  width: auto;
  margin-top: 0;
}

.table-wrap {
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}

.data-table th {
  text-align: left;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: #8b91a0;
  background: #1a1f2b;
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
}

.data-table td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line-soft);
}

.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: rgba(232, 162, 61, 0.05); }

/* Deactivated (active = 0) rows on the settings page: kept in the list,
   dimmed, with a Restore button. */
.data-table tr.dim td { opacity: 0.5; }

.tag {
  display: inline-block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  border-radius: 999px;
  padding: 2px 9px;
  border: 1px solid #3a4152;
  background: #1c212d;
  color: var(--muted);
}

.tag-residential {
  background: rgba(232, 162, 61, 0.12);
  border-color: rgba(232, 162, 61, 0.4);
  color: var(--accent-bright);
}

.tag-business {
  background: rgba(255, 138, 76, 0.10);
  border-color: rgba(255, 138, 76, 0.35);
  color: #ff9e62;
}

.custlist-empty,
.custlist-loading {
  padding: 14px 4px;
}

/* CSV import outcome under the toolbar (customers + tickets pages): one
   summary line plus per-row skip reasons (error class) and ignored-column
   names (muted). */
.import-result {
  padding: 8px 4px;
  font-size: 13.5px;
}
.import-result div { margin: 2px 0; }
.import-result .muted { color: var(--muted); font-size: 13px; }

/* ---------- tickets page ---------- */

.status-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(155px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.status-card {
  appearance: none;
  font: inherit;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-card:hover { border-color: var(--accent); }

.status-card.active {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1px var(--accent);
}

.sc-count {
  font-size: 20px;
  font-weight: 700;
  min-width: 1.2em;
}

.sc-label {
  flex: 1;
  font-size: 12.5px;
  color: var(--muted);
  line-height: 1.2;
}

.status-card.active .sc-label { color: var(--accent); }

.sc-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
  display: inline-block;
}

.tickets-table th { vertical-align: top; }

.tk-filter-row th { padding: 6px 8px; }

.tickets-table th input,
.tickets-table th select {
  margin-top: 0;
  padding: 4px 8px;
  font-size: 12.5px;
}

th.sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

th.sortable:hover { color: var(--ink); }
th.sortable.sorted-asc::after { content: ' ▲'; font-size: 9px; }
th.sortable.sorted-desc::after { content: ' ▼'; font-size: 9px; }

.data-table tbody tr.row-click { cursor: pointer; }
/* ---------- ticket form / detail page ---------- */

.head-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}

.tf-grid {
  display: grid;
  gap: 14px;
}

.tf-grid.two-col {
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  align-items: start;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.tf-side ul {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
}

.tf-side li {
  border-bottom: 1px solid var(--line);
  padding: 8px 0;
  font-size: 13.5px;
}

.tf-side li:last-child { border-bottom: none; }

.li-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.li-meta {
  color: var(--muted);
  font-size: 12px;
  display: block;
  margin-top: 2px;
}

.li-remove {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  padding: 2px 6px;
  border-radius: 6px;
  flex: 0 0 auto;
}

.li-remove:hover {
  color: var(--danger);
  background: rgba(226, 87, 79, 0.14);
}

.tag-outgoing {
  background: rgba(126, 162, 255, 0.12);
  border-color: rgba(126, 162, 255, 0.4);
  color: #a5c0ff;
}

.tag-incoming {
  background: rgba(255, 138, 76, 0.10);
  border-color: rgba(255, 138, 76, 0.35);
  color: #ff9e62;
}

/* ---------- customer detail page ---------- */

.cd-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 14px;
  align-items: start;
  margin-bottom: 14px;
}

.cd-info-row {
  display: flex;
  gap: 10px;
  padding: 4px 0;
  font-size: 14px;
}

.cd-info-label {
  color: var(--muted);
  width: 130px;
  flex: 0 0 auto;
}

.cd-info-row textarea {
  flex: 1;
  min-width: 0;
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13.5px;
  resize: vertical;
}

.contact-row {
  border-bottom: 1px solid var(--line);
  padding: 10px 0;
}

.contact-row:last-child { border-bottom: none; }

.contact-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.contact-name { font-weight: 600; }

.contact-meta {
  color: var(--muted);
  font-size: 12.5px;
  margin: 2px 0 6px;
}

.contact-actions {
  margin-left: auto;
  display: flex;
  gap: 6px;
  align-items: center;
}

.contact-chips {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}

.chip {
  appearance: none;
  font: inherit;
  font-size: 12px;
  border-radius: 999px;
  padding: 2px 10px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}

.chip.on {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}

.card-head h2 { margin: 0; }

.contact-fields {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1.3fr;
  gap: 8px;
  margin-bottom: 6px;
}

.contact-fields input {
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13.5px;
}

.section-grid {
  display: grid;
  gap: 14px;
}

.data-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.data-list li {
  border-bottom: 1px solid var(--line);
  padding: 8px 0;
  font-size: 13.5px;
}

.data-list li:last-child { border-bottom: none; }

.li-flex {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  align-items: baseline;
}

/* ---------- catalog page ---------- */

.cat-tabs {
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
}

.cat-tab {
  appearance: none;
  font: inherit;
  font-size: 14px;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}

.cat-tab:hover { color: var(--ink); }

.cat-tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}

.toolbar .check {
  flex: 0 0 auto;
  margin-bottom: 0;
  white-space: nowrap;
}

.tag-low {
  background: rgba(255, 138, 76, 0.10);
  border-color: rgba(255, 138, 76, 0.35);
  color: #ff9e62;
  margin-left: 6px;
}

/* Built-in services (seeded phone repairs): permanent, can be edited but
   never deactivated — the catalog list labels them so the guard is visible. */
.tag-built-in {
  background: rgba(126, 162, 255, 0.12);
  border-color: rgba(126, 162, 255, 0.4);
  color: #a5c0ff;
  margin-left: 6px;
}

/* ---------- document editor (estimates + invoices) ---------- */

.doc-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.doc-customer-link { font-size: 14px; }

.doc-lines-head,
.doc-line {
  display: grid;
  /* description | qty | unit price | taxable | amount | actions.
     The actions column is FIXED (wide enough for the ✕) so the blank
     trailing row — whose ✕ only appears once the row is filled — never
     shifts the other columns relative to the header and the rows above
     (same trick as the PO lines editor). */
  grid-template-columns: minmax(0, 1fr) 72px 106px 56px 96px 28px;
  gap: 8px;
  align-items: center;
}

.doc-lines-head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  padding-bottom: 6px;
}

.doc-lines-head .dl-h-amount { text-align: right; }

.doc-line { margin-bottom: 8px; }

/* The description cell hosts the per-row catalog typeahead — the dropdown
   floats over what follows (same pattern as the PO part search). */
.doc-line-desc {
  position: relative;
  min-width: 0;
}

.doc-line-desc input { width: 100%; }

.doc-line-desc .results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 30;
  margin: 2px 0 0;
  max-height: 240px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* The whole row is the click target (and arrow-key target). */
.doc-line-desc .result {
  cursor: pointer;
}

.doc-line-desc .result:hover {
  background: rgba(255, 255, 255, 0.05);
}

/* Keyboard-highlighted row (arrow keys) — same treatment as the
   phone-parts cascade's typeahead. */
.doc-line-desc .result.hi {
  background: var(--accent-soft, rgba(28, 35, 51, 0.08));
}

.doc-line input[type="text"],
.doc-line input[type="number"] {
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13.5px;
}

.doc-line .check { margin-bottom: 0; }

.dl-amount {
  text-align: right;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.dl-actions {
  display: flex;
  gap: 4px;
  justify-content: flex-end;
}

.dl-move {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  padding: 4px 7px;
}

.dl-move:hover:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent);
}

.dl-move:disabled { opacity: 0.35; cursor: default; }

.doc-totals-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}

.doc-total-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 0;
  font-size: 14px;
}

.doc-total-row span { color: var(--muted); }

.doc-grand {
  border-top: 1px solid var(--line);
  margin-top: 6px;
  padding-top: 8px;
  font-size: 16px;
}

.doc-grand span { color: var(--ink); }

.tag-paid {
  background: rgba(69, 192, 125, 0.12);
  border-color: rgba(69, 192, 125, 0.4);
  color: var(--ok);
}

/* ---------- purchase orders ---------- */

/* status tags: pending = neutral (default .tag), ordered = blue,
   received = green */
.tag-ordered {
  background: rgba(126, 162, 255, 0.12);
  border-color: rgba(126, 162, 255, 0.4);
  color: #a5c0ff;
}

.tag-received {
  background: rgba(69, 192, 125, 0.12);
  border-color: rgba(69, 192, 125, 0.4);
  color: var(--ok);
}

/* generate-PO result rows: clickable to open the generated PO */
.cg-row { cursor: pointer; }
.cg-row:hover { background: var(--accent-soft); }

.po-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.po-totals { max-width: 320px; }

/* lines editor (create / edit while open) — mirrors the document editor */
.po-lines-edit-head,
.po-line {
  display: grid;
  /* description | UPC | qty | unit cost | line amount | actions
     The actions column is FIXED (wide enough for Create part + remove) so
     ad-hoc rows — which carry an extra button — never shift the other
     columns relative to the header. */
  grid-template-columns: minmax(0, 1fr) 150px 72px 106px 96px 44px;
  gap: 8px;
  align-items: center;
}

.po-lines-edit-head {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  padding-bottom: 6px;
  align-items: end;
}

.po-line-upc {
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.po-lines-edit-head .dl-h-amount { text-align: right; }

.po-line { margin-bottom: 8px; }

.po-line input[type="text"],
.po-line input[type="number"] {
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13.5px;
}

.po-line-part {
  position: relative;
  min-width: 0;
  display: flex;
  gap: 4px;
  align-items: center;
}

.po-line-part .po-mk-part {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* the per-row part-search dropdown floats over what follows */
.po-line-part .results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 30;
  margin: 2px 0 0;
  max-height: 240px;
  overflow-y: auto;
  box-shadow: 0 6px 18px rgba(28, 35, 51, 0.12);
}

/* The whole row is the click target (and arrow-key target). */
.po-line-part .result {
  cursor: pointer;
}

.po-line-part .result:hover {
  background: rgba(255, 255, 255, 0.05);
}

/* Keyboard-highlighted row (arrow keys) — same treatment as the
   phone-parts cascade's typeahead. */
.po-line-part .result.hi {
  background: var(--accent-soft, rgba(28, 35, 51, 0.08));
}

/* received x/y progress on the detail lines table */
.po-progress {
  height: 6px;
  max-width: 120px;
  margin-top: 5px;
  background: #232a38;
  border-radius: 999px;
  overflow: hidden;
}

.po-progress span {
  display: block;
  height: 100%;
  background: var(--ok);
  border-radius: 999px;
}

.po-receive-cell {
  display: flex;
  align-items: center;
  gap: 6px;
}

.po-receive-cell input {
  width: 76px;
  margin-top: 0;
  padding: 4px 8px;
  font-size: 13px;
}

.po-lines-table td { vertical-align: top; }

/* ---------- customer billing card ---------- */

.data-list li.row-click { cursor: pointer; }

.data-list li.row-click:hover { background: rgba(232, 162, 61, 0.05); }

.billing-settings-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.billing-settings-row label { margin-bottom: 0; }

.billing-settings-row input { width: 120px; }

/* ---------- payments (billing card): enter + allocate ---------- */

/* Helcim.js writes errors/transaction results into this div. */
.helcimjs-results {
  min-height: 4px;
  margin-bottom: 8px;
  color: #ff8177;
  font-size: 13px;
}

/* Row action buttons (payment rows, saved-card rows, reader rows). */
.cd-pay-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}

.cd-pay-form {
  border-top: 1px solid var(--line);
  margin-top: 12px;
  padding-top: 12px;
}

.cd-pay-form-title { margin-bottom: 8px; }

.cd-pay-allocs { margin-top: 10px; }

.cd-pay-alloc-controls {
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
}

.cd-pay-alloc-amt {
  width: 90px;
  text-align: right;
}

.cd-pay-remaining {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-top: 1px solid var(--line);
  margin-top: 8px;
  padding-top: 8px;
}

/* Over-allocated: the payment can't cover the entered amounts. */
.cd-pay-remaining.neg { color: var(--danger); }

.cd-pay-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 4px;
}

/* ---------- recurring services (customer detail page) ---------- */

.cd-rs-form {
  border-top: 1px solid var(--line);
  margin-top: 10px;
  padding-top: 10px;
}

.cd-rs-form-title { display: block; margin-bottom: 8px; }

.cd-rs-items-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 10px 0 6px;
}

.cd-rs-item { margin-bottom: 8px; }

.cd-rs-item-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 64px 96px auto;
  gap: 8px;
  align-items: center;
}

.cd-rs-item-grid input[type="text"],
.cd-rs-item-grid input[type="number"] {
  margin-top: 0;
  padding: 6px 9px;
  font-size: 13.5px;
}

.cd-rs-item-actions {
  display: flex;
  gap: 4px;
  justify-content: flex-end;
}

.cd-rs-contract-actions,
.cd-rs-sign-row { margin-top: 8px; }

.cd-rs-attach-row,
.cd-rs-sign-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 6px;
}

/* ---------- create-part modal (purchase orders) ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(4, 6, 10, 0.62);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200000;
  pointer-events: auto;
}

.modal {
  background: var(--surface-2);
  border: 1px solid #303848;
  border-radius: 12px;
  padding: 18px;
  width: 460px;
  max-width: calc(100vw - 32px);
  max-height: 90vh;
  overflow: auto;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
}

.modal h2 { margin: 0 0 12px; font-size: 16px; }

.po-lines-edit .result {
  cursor: pointer;
}

.po-lines-edit .result:hover {
  background: var(--accent-soft);
}

/* ---------- contract editor (settings) ---------- */

.ct-toolbar {
  display: flex;
  gap: 4px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 6px;
}

/* Contract text sits on real paper (it gets printed/PDF'd) — keep it light
   even in the dark theme, like a sheet pulled from the folder. */
.ct-editor {
  min-height: 300px;
  max-height: 55vh;
  overflow: auto;
  border: 1px solid #3a3428;
  border-radius: 8px;
  background: var(--paper);
  color: var(--paper-ink);
  padding: 14px 16px;
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 14.5px;
  line-height: 1.55;
  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.18);
}

.ct-editor:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(232, 162, 61, 0.16), inset 0 2px 8px rgba(0, 0, 0, 0.18);
}

.ct-editor ul,
.ct-editor ol {
  padding-left: 24px;
  margin: 8px 0;
}

.set-ct-pdf-mode { margin: 12px 0 6px; }

/* ---------- signature pad ---------- */

.sig-canvas {
  display: block;
  width: 100%;
  height: 200px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  touch-action: none;
  cursor: crosshair;
}

/* ---------- finance (cashbox + monthly stats) ---------- */

.fin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.fin-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px 12px;
}

.fin-stat-accent {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.fin-stat-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
}

.fin-stat-value {
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.3px;
}

.fin-stat-sub {
  font-size: 12px;
  color: var(--muted);
}

.fin-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 24px;
  margin: 4px 0 12px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  font-size: 13.5px;
}

.fin-strip strong { font-variant-numeric: tabular-nums; }

/* ---------- global search (topbar) ---------- */

.globalsearch {
  position: relative;
  margin-left: auto;
  width: 340px;
  min-width: 180px;
}

.gs-box {
  display: flex;
  align-items: center;
  gap: 6px;
  background: #10141c;
  border: 1px solid #2b3244;
  border-radius: 8px;
  padding: 5px 10px;
  transition: background 0.12s, border-color 0.12s;
}

.gs-box:focus-within {
  background: #141924;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(232, 162, 61, 0.14);
}

.gs-icon {
  font-size: 12px;
  opacity: 0.55;
  flex: none;
}

.gs-box input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  outline: 0;
  font: inherit;
  font-size: 14px;
  color: var(--ink);
}

.gs-box input::placeholder { color: var(--muted); }

.gs-kbd {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--accent-bright);
  border: 1px solid #3a4152;
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 0 6px;
  line-height: 17px;
  background: #1c212d;
}

.gs-box:focus-within .gs-kbd,
.gs-box.has-text .gs-kbd { display: none; }

.gs-clear {
  flex: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
  border-radius: 5px;
}

.gs-clear:hover { color: var(--ink); background: rgba(255, 255, 255, 0.08); }

.gs-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 480px;
  max-width: calc(100vw - 32px);
  max-height: min(560px, 75vh);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 14px 36px rgba(28, 35, 51, 0.18);
  z-index: 60000; /* above floating windows (500) */
  padding-bottom: 2px;
}

.gs-filterbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 14px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  color: var(--accent);
  font-weight: 600;
  position: sticky;
  top: 0;
}

.gs-filterbar-x {
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 5px;
}

.gs-filterbar-x:hover { background: #dbe4ff; }

.gs-group + .gs-group,
.gs-group + .gs-empty { border-top: 1px solid var(--line); }

.gs-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 5px;
  cursor: pointer;
  user-select: none;
}

.gs-head:hover,
.gs-head:hover .gs-head-label,
.gs-head:hover .gs-head-count {
  color: var(--accent);
}

.gs-head-label {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
}

.gs-head-count {
  font-size: 11px;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0 6px;
  line-height: 15px;
}

.gs-head-label { flex: none; }

/* push the count to the right edge of the header */
.gs-head-count { margin-left: auto; }
.gs-head::after {
  content: 'filter';
  font-size: 10.5px;
  color: var(--accent);
  opacity: 0;
  transition: opacity 0.1s;
}

.gs-head:hover::after { opacity: 0.8; }

.gs-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  cursor: pointer;
}

.gs-item.active { background: var(--accent-soft); }

.gs-item-main { flex: 1; min-width: 0; }

.gs-item-title {
  font-weight: 600;
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gs-item-sub {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gs-badge {
  flex: none;
  font-size: 11px;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 1px 7px;
  text-transform: capitalize;
}

.gs-badge-good {
  color: var(--ok);
  border-color: rgba(69, 192, 125, 0.4);
  background: rgba(69, 192, 125, 0.10);
}

.gs-badge-bad {
  color: var(--danger);
  border-color: rgba(226, 87, 79, 0.4);
  background: rgba(226, 87, 79, 0.10);
}

.gs-empty {
  padding: 12px 14px;
  color: var(--muted);
  font-size: 13px;
}

.gs-hintbar {
  border-top: 1px solid var(--line);
  padding: 7px 14px;
  color: var(--muted);
  font-size: 11.5px;
  background: var(--bg);
  border-radius: 0 0 10px 10px;
}

@media (max-width: 980px) {
  .globalsearch { width: 220px; }
  .topnav { gap: 0; }
  .topnav a { padding: 7px 8px; }
}

/* keyboard-selected header / filter chip (global search) */
.gs-head.active { background: var(--accent-soft); }
.gs-head.active::after { opacity: 0.8; }
.gs-head.active .gs-head-label,
.gs-head.active .gs-head-count { color: var(--accent); }
.gs-filterbar.active { background: rgba(232, 162, 61, 0.22); }

/* ---------- signed-in user chip (topbar) ---------- */

.userbox {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: 14px;
  flex: none;
}

.userbox-name {
  font-size: 13.5px;
  color: var(--muted);
  white-space: nowrap;
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* "Set" password tag on the users list */
.tag-ok {
  background: #e7f5ec;
  border-color: #bfe4cd;
  color: var(--ok);
}

/* Standalone error text (login page, password window) — the base .error is
   shaped for savebars (flex + right-aligned). */
.login-error,
.pw-win .error {
  flex: none;
  display: block;
  text-align: left;
  margin: 2px 0 10px;
}

/* ---------- login page (web/login.html) ---------- */

body.login-body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 24px;
  background:
    radial-gradient(900px 480px at 12% -6%, rgba(232, 162, 61, 0.16) 0%, transparent 55%),
    radial-gradient(700px 420px at 108% 108%, rgba(232, 162, 61, 0.07) 0%, transparent 55%),
    var(--bg);
}

.login-card {
  width: 100%;
  max-width: 360px;
  background: var(--surface-2);
  border: 1px solid #303848;
  border-radius: 14px;
  box-shadow:
    0 30px 70px rgba(0, 0, 0, 0.55),
    0 0 60px rgba(232, 162, 61, 0.06);
  padding: 30px 30px 22px;
}

.login-brand {
  font-size: 21px;
  text-align: center;
}

.login-sub {
  text-align: center;
  color: var(--muted);
  font-size: 13.5px;
  margin: 4px 0 22px;
}

.login-btn {
  width: 100%;
  justify-content: center;
  margin-top: 4px;
}

.login-hint {
  margin: 18px 0 0;
  text-align: center;
}

/* ===========================================================================
   DESK THEME — "the shop after hours"
   A dark room lit by a banker's lamp. The top nav is a manila folder (each
   page is a tab; the active page's tab is pulled forward and opened), every
   button is a keycap, and the dashboard is the desk itself: wood, keypad,
   lamp, coffee. Section order below: folder chrome → keycaps → scene.
   =========================================================================== */

/* ---------- keyboard focus ring (a11y) ---------- */

button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--accent-bright);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- room vignette (over everything, catches nothing) ---------- */

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 999999;
  background: radial-gradient(125% 95% at 50% 28%, transparent 52%, rgba(3, 4, 7, 0.45) 100%);
}

body.lamp-off::after {
  background: radial-gradient(125% 95% at 50% 28%, transparent 40%, rgba(2, 3, 5, 0.62) 100%);
}

/* ---------- topbar: the manila folder ---------- */

.topbar {
  height: 56px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  position: relative;
  background:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.045) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, #4a3f2a 0%, #3d3322 10%, #2d2617 100%);
  border-bottom: 1px solid #120f08;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

/* lamp catch on the folder's top edge + a lip where the folder opens */
.topbar::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: linear-gradient(90deg, rgba(255, 205, 120, 0.4), rgba(255, 205, 120, 0.08) 45%, transparent 72%);
}

.topbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  background: linear-gradient(180deg, rgba(255, 222, 150, 0.16), rgba(0, 0, 0, 0.38));
  pointer-events: none;
}

/* the shop's stamp on the folder face */
.brand {
  font-weight: 800;
  font-size: 14.5px;
  letter-spacing: 0.3px;
  color: #e6d9b8;
  background: #241d10;
  border: 1px solid #57492f;
  border-radius: 6px;
  padding: 5px 11px 6px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 2px 6px rgba(0, 0, 0, 0.45);
}

.brand span { color: var(--accent-bright); }

/* ---------- folder tabs (nav) ---------- */

.topnav {
  align-self: stretch;
  display: flex;
  align-items: flex-end;
  gap: 3px;
  margin-left: 26px;
}

.topnav a {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 30px;
  margin-bottom: 5px; /* inactive tabs sit lifted, unopened */
  padding: 0 17px 2px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  color: #b4a67f;
  text-decoration: none;
  background: linear-gradient(180deg, #584a30 0%, #4a3e27 100%);
  border-radius: 8px 8px 0 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    0 -4px 10px rgba(0, 0, 0, 0.18);
  transition: background 0.15s, color 0.15s, margin-bottom 0.15s, box-shadow 0.15s;
}

/* slanted shoulders turn each link into an old folder tab */
.topnav a::before,
.topnav a::after {
  content: "";
  position: absolute;
  top: 3px;
  bottom: 0;
  width: 11px;
  background: inherit;
  z-index: -1;
}

.topnav a::before {
  left: -6px;
  transform: skewX(-16deg);
  border-radius: 4px 0 0 0;
}

.topnav a::after {
  right: -6px;
  transform: skewX(16deg);
  border-radius: 0 4px 0 0;
}

.topnav a:hover {
  color: #e2d5ae;
  background: linear-gradient(180deg, #66562f 0%, #524525 100%);
}

/* the open tab: pulled down to the folder body, warm paper, lamp-lit */
.topnav a.active {
  margin-bottom: 0;
  height: 35px;
  padding-bottom: 3px;
  color: #4a3a15;
  background: linear-gradient(180deg, #ecd8a4 0%, #d3bd85 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 0 22px rgba(232, 162, 61, 0.22),
    0 3px 8px rgba(0, 0, 0, 0.3);
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
}

.topnav a.active::before,
.topnav a.active::after {
  background: #d3bd85;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

/* ---------- desk-lamp switch (topbar) ---------- */

.lamp-toggle {
  appearance: none;
  font: inherit;
  margin-left: 12px;
  flex: none;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px solid #0b0e14;
  background: linear-gradient(180deg, #323a4d 0%, #262c3a 60%, #1e2330 100%);
  color: var(--accent-bright);
  cursor: pointer;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 3px 0 #0d1017,
    0 4px 9px rgba(0, 0, 0, 0.45);
  transition: transform 0.05s, box-shadow 0.05s, color 0.2s, filter 0.2s;
}

.lamp-toggle:active { transform: translateY(2px); box-shadow: 0 1px 0 #0d1017; }

.lamp-toggle svg { display: block; }

.lamp-toggle .bulb-fill { fill: currentColor; }

.lamp-toggle .bulb-ray { stroke: currentColor; }

body.lamp-off .lamp-toggle {
  color: #5b6372;
  filter: saturate(0.6);
}

/* ---------- keycaps: every button is a key ---------- */

.btn {
  position: relative;
  appearance: none;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.2px;
  padding: 7px 14px 8px;
  border-radius: 8px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, var(--key-hi) 0%, var(--key) 55%, #1e2330 100%);
  color: var(--key-ink);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.45);
  cursor: pointer;
  transform: translateY(0);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -2px 3px rgba(0, 0, 0, 0.3),
    0 3px 0 var(--key-side),
    0 5px 10px rgba(0, 0, 0, 0.45);
  transition: transform 0.05s ease, box-shadow 0.05s ease, filter 0.12s ease, color 0.12s ease;
}

.btn:hover:not(:disabled) {
  color: #ffd98f;
  filter: brightness(1.14);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -2px 3px rgba(0, 0, 0, 0.3),
    0 4px 0 var(--key-side),
    0 7px 14px rgba(0, 0, 0, 0.5);
}

.btn:active:not(:disabled) {
  transform: translateY(3px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 2px 4px rgba(0, 0, 0, 0.42),
    0 0 0 var(--key-side),
    0 1px 3px rgba(0, 0, 0, 0.5);
}

.btn:disabled { opacity: 0.45; transform: none; box-shadow: 0 1px 0 var(--key-side); }

.btn-small { padding: 4px 10px 5px; font-size: 12.5px; border-radius: 7px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 0 var(--key-side), 0 3px 7px rgba(0, 0, 0, 0.4); }
.btn-small:active:not(:disabled) { transform: translateY(2px); box-shadow: 0 0 0 var(--key-side), 0 1px 2px rgba(0, 0, 0, 0.4); }

/* primary = the amber "escape" key the lamp is shining on */
.btn-primary {
  background: linear-gradient(180deg, #ffce6b 0%, #e8a23d 55%, #c8831f 100%);
  border-color: #6b440c;
  color: #2a1a04;
  font-weight: 700;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -2px 3px rgba(120, 70, 10, 0.35),
    0 3px 0 #8a5a10,
    0 5px 14px rgba(232, 162, 61, 0.28);
}

.btn-primary:hover:not(:disabled) {
  color: #2a1a04;
  background: linear-gradient(180deg, #ffd987 0%, #f2ae47 55%, #d18d24 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -2px 3px rgba(120, 70, 10, 0.35),
    0 4px 0 #8a5a10,
    0 7px 18px rgba(232, 162, 61, 0.38);
}

.btn-primary:active:not(:disabled) {
  box-shadow:
    inset 0 2px 5px rgba(120, 70, 10, 0.45),
    0 0 0 #8a5a10,
    0 1px 4px rgba(232, 162, 61, 0.2);
}

/* mini keycaps: taskbar chips, catalog pills, contact chips, line buttons */
.taskchip {
  font-weight: 600;
  font-size: 12.5px;
  border-radius: 8px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, var(--key-hi) 0%, var(--key) 60%, #1e2330 100%);
  color: var(--key-ink);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 2px 0 var(--key-side),
    0 3px 7px rgba(0, 0, 0, 0.4);
  transition: transform 0.05s, box-shadow 0.05s, filter 0.12s, color 0.12s;
}

.taskchip:hover { color: #ffd98f; filter: brightness(1.12); }

.taskchip:active { transform: translateY(2px); box-shadow: 0 0 0 var(--key-side); }

.taskchip.active {
  background: linear-gradient(180deg, #ffce6b 0%, #e8a23d 60%, #c8831f 100%);
  border-color: #6b440c;
  color: #2a1a04;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 2px 0 #8a5a10, 0 4px 12px rgba(232, 162, 61, 0.3);
}

.cat-tab {
  font-weight: 600;
  border-radius: 8px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, var(--key-hi) 0%, var(--key) 60%, #1e2330 100%);
  color: var(--key-ink);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 2px 0 var(--key-side),
    0 3px 7px rgba(0, 0, 0, 0.4);
  transition: transform 0.05s, box-shadow 0.05s, filter 0.12s, color 0.12s;
}

.cat-tab:hover { color: #ffd98f; filter: brightness(1.12); }

.cat-tab:active { transform: translateY(2px); box-shadow: 0 0 0 var(--key-side); }

.cat-tab.active {
  background: linear-gradient(180deg, #ffce6b 0%, #e8a23d 60%, #c8831f 100%);
  border-color: #6b440c;
  color: #2a1a04;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 2px 0 #8a5a10, 0 4px 12px rgba(232, 162, 61, 0.3);
}

.chip {
  border-radius: 7px;
  border: 1px solid #2b3244;
  background: #1a1f2b;
  box-shadow: 0 1px 0 #0d1017;
}

.chip:active { transform: translateY(1px); }

.chip.on {
  background: linear-gradient(180deg, #ffce6b 0%, #e8a23d 70%, #c8831f 100%);
  border-color: #6b440c;
  color: #2a1a04;
  font-weight: 700;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 1px 0 #8a5a10, 0 2px 8px rgba(232, 162, 61, 0.3);
}

.dl-move {
  border-radius: 6px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, var(--key-hi) 0%, var(--key) 70%);
  color: #b7bfce;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 0 var(--key-side);
}

.dl-move:hover:not(:disabled) { color: #ffd98f; filter: brightness(1.15); }

.dl-move:active:not(:disabled) { transform: translateY(1px); box-shadow: 0 0 0 var(--key-side); }

.li-remove {
  border-radius: 6px;
  transition: color 0.12s, background 0.12s, transform 0.05s;
}

.li-remove:active { transform: translateY(1px); }

/* filter cards on the tickets page get a soft keycap press too */
.status-card {
  border-radius: 10px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, var(--surface-3) 0%, var(--surface-2) 70%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 3px 0 #0d1017,
    0 5px 12px rgba(0, 0, 0, 0.35);
  transition: transform 0.05s, box-shadow 0.05s, border-color 0.12s;
}

.status-card:hover { border-color: #39415a; }

.status-card:active { transform: translateY(2px); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 0 #0d1017; }

.status-card.active {
  border-color: rgba(232, 162, 61, 0.65);
  background: linear-gradient(180deg, #33291a 0%, #2b2216 70%);
  box-shadow:
    inset 0 1px 0 rgba(255, 197, 97, 0.14),
    inset 0 0 0 1px rgba(232, 162, 61, 0.35),
    0 3px 0 #0d1017,
    0 6px 16px rgba(232, 162, 61, 0.1);
}

.status-card.active .sc-label { color: var(--accent-bright); }

/* ---------- shared surfaces ---------- */

.card {
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 100%);
  border: 1px solid #262d3d;
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.3);
}

.card h2 { color: #8d93a0; }

.table-wrap {
  border: 1px solid #262d3d;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.32);
}

.gs-panel {
  background: #161a24;
  border: 1px solid #303848;
  box-shadow: 0 26px 64px rgba(0, 0, 0, 0.62), 0 0 40px rgba(232, 162, 61, 0.05);
}

.taskbar {
  background: linear-gradient(180deg, #151925, #0e1119);
  border-top: 1px solid #2b3244;
  box-shadow: 0 -10px 28px rgba(0, 0, 0, 0.5);
}

/* ---------- toasts ----------
   Short-lived confirmations that float above everything (windows sit at
   z-index 1000+): stacked bottom-right, above the taskbar, auto-fading. */
#toast-stack {
  position: fixed;
  right: 16px;
  bottom: 64px;
  z-index: 6000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  pointer-events: none;
}

.toast {
  max-width: 340px;
  background: var(--surface-2);
  border: 1px solid rgba(232, 162, 61, 0.45);
  border-radius: 8px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  color: var(--ink);
  font-size: 13.5px;
  padding: 10px 14px;
  animation: toast-in 0.18s ease-out;
}

.toast-out {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.32s ease-in, transform 0.32s ease-in;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

/* ---------- the desk (dashboard) ----------
   Scene stack, back to front:
     .desk-room    dark wall + floor
     .desk-surface walnut top, planks + grain
     .lamp-pool    warm ellipse of lamplight on the wood
     .desk-lamp    the banker's lamp (base, two arms, green shade, bulb)
     .keyboard     the BETTRDECK keypad — every quick action is a keycap
     .desk-props   coffee, sticky note, screwdriver, cracked phone, mouse
     .lamp-cone    the cone of light, blended over everything (screen)      */

.desk-page { max-width: 1240px; }

.desk-scene {
  position: relative;
  margin-top: 4px;
  min-height: 660px;
  padding: 10px 12px 46px;
  perspective: 1400px;
  /* JS parallax target (desk.js): the keypad leans a hair toward the cursor */
  --tilt-x: 0deg;
  --tilt-y: 0deg;
}

.desk-room {
  position: absolute;
  inset: -28px -30px 0;
  border-radius: 12px;
  overflow: hidden;
  background:
    /* faint moonlight leaking from a far window, opposite the lamp */
    radial-gradient(420px 300px at 92% 12%, rgba(140, 160, 200, 0.05), transparent 70%),
    linear-gradient(180deg, #14161d 0%, #101218 46%, #0b0d12 100%);
}

/* the floor line behind the desk edge */
.desk-room::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 30%;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5) 55%, #07080c);
}

.desk-surface {
  position: absolute;
  left: -4%;
  right: -4%;
  top: 44%;
  bottom: -4px;
  border-radius: 16px 16px 10px 10px;
  background:
    /* plank gaps */
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.22) 0 2px, transparent 2px 128px),
    /* fine grain */
    repeating-linear-gradient(88.6deg, rgba(255, 255, 255, 0.016) 0 2px, transparent 2px 7px),
    repeating-linear-gradient(91.4deg, rgba(0, 0, 0, 0.06) 0 1px, transparent 1px 11px),
    linear-gradient(180deg, #503a26 0%, #43301f 26%, #352517 62%, #291c11 100%);
  box-shadow:
    0 -2px 0 rgba(255, 200, 120, 0.08),
    0 -14px 34px rgba(0, 0, 0, 0.5),
    0 26px 60px rgba(0, 0, 0, 0.6);
}

/* warm ellipse of lamplight pooling on the wood */
.lamp-pool {
  position: absolute;
  left: 6%;
  top: 52%;
  width: 64%;
  height: 40%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 202, 122, 0.22), rgba(255, 190, 100, 0.07) 55%, transparent 75%);
  filter: blur(6px);
  mix-blend-mode: screen;
  pointer-events: none;
  z-index: 2;
  animation: lamp-breathe 7.3s ease-in-out infinite;
}

/* ---------- the banker's lamp ---------- */

.desk-lamp {
  position: absolute;
  left: 3.5%;
  top: 15%;
  width: 250px;
  height: 340px;
  z-index: 3;
  pointer-events: none;
}

.lamp-base {
  position: absolute;
  bottom: 6px;
  left: 44px;
  width: 108px;
  height: 18px;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 30%, #3d4652 0%, #232a33 55%, #12161c 100%);
  box-shadow:
    0 4px 10px rgba(0, 0, 0, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

.lamp-base::after {
  /* brass hub where the arm meets the base */
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  width: 26px;
  height: 12px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 35%, #f0d492 0%, #c9a24e 45%, #8a6a24 100%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
}

.lamp-arm {
  position: absolute;
  width: 9px;
  border-radius: 5px;
  background: linear-gradient(90deg, #4b5563 0%, #2b323c 45%, #171c23 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 2px 3px 6px rgba(0, 0, 0, 0.4);
}

.lamp-arm-a {
  bottom: 14px;
  left: 92px;
  height: 168px;
  transform: rotate(14deg);
  transform-origin: 50% 100%;
}

.lamp-joint {
  position: absolute;
  left: 130px;
  bottom: 158px;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #f0d492 0%, #c9a24e 48%, #8a6a24 100%);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
}

.lamp-arm-b {
  left: 136px;
  bottom: 166px;
  height: 116px;
  transform: rotate(48deg);
  transform-origin: 50% 100%;
}

/* green glass shade, brass rim, mouth aimed at the keypad */
.lamp-head {
  position: absolute;
  left: 176px;
  bottom: 232px;
  width: 100px;
  height: 58px;
  transform: rotate(24deg);
  transform-origin: 50% 20%;
  clip-path: polygon(26% 0, 74% 0, 100% 100%, 0 100%);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.1), transparent 30%),
    linear-gradient(180deg, #2a6b57 0%, #1d4c3d 55%, #12352a 100%);
  filter: drop-shadow(0 0 1px rgba(214, 178, 94, 0.85)) drop-shadow(0 3px 5px rgba(0, 0, 0, 0.45));
}

/* hot mouth of the shade */
.lamp-head::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: -1px;
  height: 12px;
  border-radius: 0 0 8px 8px;
  background: linear-gradient(180deg, rgba(255, 236, 180, 0.85), rgba(255, 205, 120, 0.15));
  filter: blur(1px);
}

.lamp-bulb {
  position: absolute;
  left: 218px;
  bottom: 216px;
  width: 44px;
  height: 18px;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 40%, #fff6dd 0%, #ffd98e 55%, rgba(255, 190, 100, 0) 100%);
  box-shadow:
    0 0 24px 10px rgba(255, 205, 120, 0.5),
    0 0 70px 26px rgba(255, 190, 100, 0.22);
  animation: lamp-breathe 7.3s ease-in-out infinite;
}

/* ---------- the cone of light ---------- */

.lamp-cone {
  position: absolute;
  left: 2%;
  top: 8%;
  width: 74%;
  height: 86%;
  pointer-events: none;
  z-index: 6;
  mix-blend-mode: screen;
  clip-path: polygon(21% 22%, 27% 20%, 100% 96%, 12% 96%);
  background: linear-gradient(206deg, rgba(255, 214, 138, 0.34) 0%, rgba(255, 202, 122, 0.16) 42%, rgba(255, 190, 100, 0.05) 68%, transparent 82%);
  filter: blur(7px);
  animation: lamp-flicker 7.3s linear infinite;
}

@keyframes lamp-breathe {
  0%, 100% { opacity: 0.92; }
  45% { opacity: 1; }
  70% { opacity: 0.88; }
}

@keyframes lamp-flicker {
  0%, 100% { opacity: 0.85; }
  9% { opacity: 0.78; }
  12% { opacity: 0.9; }
  38% { opacity: 0.82; }
  41% { opacity: 0.92; }
  66% { opacity: 0.8; }
  69% { opacity: 0.88; }
  84% { opacity: 0.84; }
}

/* ---------- hero, engraved on a plaque ---------- */

.dash-hero {
  position: relative;
  z-index: 4;
  text-align: center;
  padding: 30px 0 8px;
}

.dash-hero h1 {
  margin: 0;
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: #9aa2b1;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.85), 0 -1px 0 rgba(255, 255, 255, 0.05);
  padding: 7px 18px;
  border: 1px solid #2c3345;
  border-radius: 6px;
  background: linear-gradient(180deg, #1a1f2b, #141823);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 4px 10px rgba(0, 0, 0, 0.4);
}

.dash-hero p {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 13px;
  letter-spacing: 0.3px;
}

/* ---------- the keypad ---------- */

.keyboard {
  position: relative;
  z-index: 5;
  width: min(690px, 94%);
  margin: 26px auto 0;
  transform: rotateX(calc(8deg + var(--tilt-y))) rotateY(var(--tilt-x));
  transform-origin: 50% 0;
}

.kb-plate {
  position: relative;
  border-radius: 18px;
  padding: 30px 26px 20px;
  background:
    /* brushed metal */
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.014) 0 1px, transparent 1px 3px),
    linear-gradient(180deg, #232939 0%, #1b202c 60%, #151923 100%);
  border: 1px solid #07090d;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.09),
    inset 0 -3px 8px rgba(0, 0, 0, 0.5),
    0 3px 0 #0a0c11,
    0 26px 48px rgba(0, 0, 0, 0.6),
    0 40px 90px rgba(0, 0, 0, 0.5);
}

/* lamp sheen raking across the plate */
.kb-plate::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    radial-gradient(340px 200px at 12% -4%, rgba(255, 200, 120, 0.14), transparent 70%),
    radial-gradient(240px 160px at 104% 108%, rgba(255, 200, 120, 0.05), transparent 70%);
  pointer-events: none;
}

.kb-brand {
  position: absolute;
  top: 10px;
  left: 20px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 2.5px;
  color: #5b6372;
  user-select: none;
}

.kb-leds {
  position: absolute;
  top: 12px;
  right: 20px;
  display: flex;
  gap: 7px;
}

.kb-leds i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #262c3a;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* power LED glows amber; the third blinks like drive activity */
.kb-leds i:first-child {
  background: var(--accent-bright);
  box-shadow: 0 0 8px rgba(255, 195, 97, 0.75), 0 0 2px rgba(255, 195, 97, 0.9);
}

.kb-leds i:last-child {
  background: #3f7d57;
  box-shadow: 0 0 6px rgba(69, 192, 125, 0.5);
  animation: led-blink 2.6s steps(1) infinite;
}

@keyframes led-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}

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

.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 13px 14px;
}

.tile {
  position: relative;
  appearance: none;
  font: inherit;
  border: 1px solid #0a0c11;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  min-height: 96px;
  padding: 12px 14px 10px;
  text-align: left;
  border-radius: 10px;
  color: var(--key-ink);
  background: linear-gradient(180deg, #333a4c 0%, #262c3a 58%, #1e2330 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    inset 0 -3px 4px rgba(0, 0, 0, 0.34),
    0 6px 0 #0d1017,
    0 13px 24px rgba(0, 0, 0, 0.55);
  transform: translateY(0);
  transition: transform 0.06s ease, box-shadow 0.06s ease, filter 0.14s ease;
}

.tile:hover:not(:disabled) {
  filter: brightness(1.15);
  transform: translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.15),
    inset 0 -3px 4px rgba(0, 0, 0, 0.34),
    0 7px 0 #0d1017,
    0 16px 28px rgba(0, 0, 0, 0.6);
}

.tile:active:not(:disabled) {
  transform: translateY(5px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 3px 6px rgba(0, 0, 0, 0.45),
    0 1px 0 #0d1017,
    0 4px 10px rgba(0, 0, 0, 0.45);
}

.tile:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 2px; }

.tile-icon {
  font-size: 16px;
  line-height: 1;
  color: #9fb4d8;
  opacity: 0.9;
  filter: saturate(0.85);
}

.tile-title {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.2px;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
}

.tile-sub {
  font-size: 10.5px;
  line-height: 1.3;
  color: #8a93a5;
}

/* intake + pickup: the amber keys under the lamp's hot spot */
.tile-primary {
  background: linear-gradient(180deg, #ffce6b 0%, #e8a23d 55%, #c8831f 100%);
  border-color: #6b440c;
  color: #2a1a04;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.5),
    inset 0 -3px 4px rgba(120, 70, 10, 0.32),
    0 6px 0 #8a5a10,
    0 14px 26px rgba(232, 162, 61, 0.3),
    0 13px 24px rgba(0, 0, 0, 0.4);
}

.tile-primary:hover:not(:disabled) {
  background: linear-gradient(180deg, #ffd987 0%, #f2ae47 55%, #d18d24 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -3px 4px rgba(120, 70, 10, 0.32),
    0 7px 0 #8a5a10,
    0 17px 30px rgba(232, 162, 61, 0.4),
    0 16px 28px rgba(0, 0, 0, 0.45);
}

.tile-primary:active:not(:disabled) {
  box-shadow:
    inset 0 2px 6px rgba(120, 70, 10, 0.45),
    0 1px 0 #8a5a10,
    0 3px 8px rgba(232, 162, 61, 0.2);
}

.tile-primary .tile-icon { color: #2a1a04; opacity: 0.85; }
.tile-primary .tile-sub { color: rgba(42, 26, 4, 0.62); }

/* disabled "soon" keys: blank caps with an engraved chip */
.tile-soon {
  background: linear-gradient(180deg, #1e2330 0%, #191d27 60%, #14171f 100%);
  cursor: default;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    inset 0 -3px 4px rgba(0, 0, 0, 0.3),
    0 4px 0 #0d1017,
    0 9px 18px rgba(0, 0, 0, 0.45);
}

.tile-soon .tile-title { color: #6b7385; font-size: 13.5px; }

.soon {
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: #6f7889;
  border: 1px solid #39415a;
  border-radius: 4px;
  padding: 1px 7px;
  background: rgba(0, 0, 0, 0.25);
}

/* ---------- spacebar row under the grid ---------- */

.kb-chrome {
  display: flex;
  align-items: stretch;
  gap: 8px;
  margin-top: 13px;
}

.kb-spacebar {
  flex: 1;
  height: 26px;
  border-radius: 7px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, #303749 0%, #232936 60%, #1c212c 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.11),
    inset 0 -2px 3px rgba(0, 0, 0, 0.3),
    0 4px 0 #0d1017;
}

.kb-k {
  flex: 0 0 30px;
  height: 26px;
  border-radius: 7px;
  border: 1px solid #0a0c11;
  background: linear-gradient(180deg, #2c3342 0%, #22272f 60%, #1a1e28 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    inset 0 -2px 3px rgba(0, 0, 0, 0.3),
    0 4px 0 #0d1017;
}

.kb-hint {
  margin: 14px 0 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: #565d6d;
}

/* ---------- desk props ---------- */

.desk-props { position: absolute; inset: 0; pointer-events: none; z-index: 4; }

/* coffee */
.prop-mug {
  position: absolute;
  right: 11%;
  top: 47%;
  width: 58px;
  height: 52px;
}

.prop-mug::before {
  /* body */
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 46px;
  height: 44px;
  border-radius: 6px 6px 10px 10px;
  background: linear-gradient(90deg, #d8d0bd 0%, #efe8d6 45%, #b7ae9a 100%);
  box-shadow: inset 0 -6px 8px rgba(0, 0, 0, 0.14), 0 6px 10px rgba(0, 0, 0, 0.5);
}

.prop-mug::after {
  /* rim + coffee */
  content: "";
  position: absolute;
  left: -3px;
  top: 2px;
  width: 52px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 42%, #2b1a10 0%, #46281a 58%, #efe8d6 60%, #d8d0bd 100%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
}

.prop-mug .mug-handle {
  position: absolute;
  right: 0;
  bottom: 12px;
  width: 16px;
  height: 22px;
  border: 5px solid #d8d0bd;
  border-left: none;
  border-radius: 0 10px 10px 0;
  box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.35);
}

.mug-steam {
  position: absolute;
  bottom: 100%;
  width: 5px;
  height: 26px;
  border-radius: 50%;
  background: linear-gradient(180deg, transparent, rgba(255, 255, 255, 0.16), transparent);
  filter: blur(2px);
  animation: steam 3.4s ease-in-out infinite;
}

.mug-steam-1 { left: 10px; animation-delay: 0s; }
.mug-steam-2 { left: 22px; height: 32px; animation-delay: 1.1s; }
.mug-steam-3 { left: 33px; animation-delay: 2.2s; }

@keyframes steam {
  0% { transform: translateY(6px) scaleY(0.9); opacity: 0; }
  30% { opacity: 0.8; }
  100% { transform: translateY(-16px) scaleY(1.15); opacity: 0; }
}

/* sticky note, taped down */
.prop-note {
  position: absolute;
  right: 4.5%;
  top: 21%;
  width: 96px;
  height: 96px;
  transform: rotate(-5deg);
  background: linear-gradient(180deg, #f3e59d 0%, #e9d57f 100%);
  border-radius: 2px;
  box-shadow:
    0 2px 2px rgba(0, 0, 0, 0.25),
    0 10px 18px rgba(0, 0, 0, 0.45);
  padding: 20px 10px 0;
}

.prop-note::before {
  /* tape */
  content: "";
  position: absolute;
  top: -9px;
  left: 22px;
  width: 50px;
  height: 18px;
  background: rgba(255, 255, 255, 0.28);
  border-left: 1px dashed rgba(255, 255, 255, 0.4);
  border-right: 1px dashed rgba(255, 255, 255, 0.4);
  transform: rotate(2deg);
}

.prop-note::after {
  /* curled bottom corner */
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  border-style: solid;
  border-width: 0 0 18px 18px;
  border-color: transparent transparent #14161d transparent;
  filter: drop-shadow(-2px -2px 2px rgba(0, 0, 0, 0.25));
}

.prop-note .note-line {
  display: block;
  height: 4px;
  border-radius: 2px;
  background: rgba(74, 58, 21, 0.55);
  margin: 0 2px 9px;
}

.prop-note .note-line.short { width: 55%; margin-left: 2px; }

/* screwdriver — it is a repair shop, after all */
.prop-driver {
  position: absolute;
  left: 30%;
  bottom: 4%;
  width: 150px;
  height: 18px;
  transform: rotate(-7deg);
}

.prop-driver .sd-handle {
  position: absolute;
  right: 0;
  top: 0;
  width: 62px;
  height: 17px;
  border-radius: 7px 8px 8px 7px;
  background:
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.18) 0 3px, transparent 3px 7px),
    linear-gradient(180deg, #f0a83f 0%, #d98c22 60%, #a9680f 100%);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

.prop-driver .sd-shaft {
  position: absolute;
  left: 16px;
  top: 5px;
  width: 78px;
  height: 7px;
  background: linear-gradient(180deg, #b9c2cf 0%, #7e8898 55%, #4a525f 100%);
  border-radius: 2px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
}

.prop-driver .sd-tip {
  position: absolute;
  left: 0;
  top: 6.5px;
  width: 18px;
  height: 4px;
  background: linear-gradient(180deg, #8f99a8 0%, #565f6e 100%);
  clip-path: polygon(0 50%, 100% 0, 100% 100%);
}

/* the shop's bread and butter: a cracked phone on the desk */
.prop-phone {
  position: absolute;
  right: 22%;
  bottom: 5%;
  width: 74px;
  height: 34px;
  transform: rotate(9deg);
  border-radius: 9px;
  border: 2px solid #0a0c11;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, 0.09) 0%, transparent 34%),
    linear-gradient(180deg, #17202f 0%, #101623 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 5px 10px rgba(0, 0, 0, 0.55);
}

.prop-phone .phone-crack {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(64deg, transparent 46%, rgba(255, 255, 255, 0.35) 47%, transparent 49%),
    linear-gradient(118deg, transparent 52%, rgba(255, 255, 255, 0.28) 53%, transparent 55%),
    linear-gradient(20deg, transparent 38%, rgba(255, 255, 255, 0.22) 39%, transparent 41%);
  opacity: 0.8;
}

/* mouse to the right of the keypad */
.prop-mouse {
  position: absolute;
  right: 5.5%;
  bottom: 24%;
  width: 46px;
  height: 62px;
  transform: rotate(-14deg);
  border-radius: 22px 22px 14px 14px;
  background:
    linear-gradient(160deg, rgba(255, 200, 120, 0.1) 0%, transparent 45%),
    linear-gradient(180deg, #2d3444 0%, #20262f 70%, #171c24 100%);
  border: 1px solid #0a0c11;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 6px 12px rgba(0, 0, 0, 0.55);
}

.prop-mouse::before {
  /* split line for the buttons */
  content: "";
  position: absolute;
  left: 50%;
  top: 4px;
  bottom: 55%;
  width: 1px;
  background: rgba(0, 0, 0, 0.4);
}

.prop-mouse .mouse-scroll {
  position: absolute;
  left: 50%;
  top: 8px;
  width: 6px;
  height: 14px;
  transform: translateX(-50%);
  border-radius: 3px;
  background: linear-gradient(180deg, #454e63 0%, #2a3140 100%);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.2);
}

/* ---------- lights out ---------- */

body.lamp-off .lamp-cone,
body.lamp-off .lamp-pool,
body.lamp-off .lamp-bulb,
body.lamp-off .lamp-head::after {
  opacity: 0.05;
  animation: none;
  transition: opacity 0.7s;
}

body.lamp-off .desk-lamp { filter: brightness(0.6) saturate(0.7); transition: filter 0.7s; }

body.lamp-off .kb-plate::before,
body.lamp-off .desk-surface {
  transition: filter 0.7s;
}

body.lamp-off .desk-surface { filter: brightness(0.62) saturate(0.72); }

body.lamp-off .kb-plate::before { opacity: 0.15; transition: opacity 0.7s; }

body.lamp-off .kb-leds i:first-child {
  background: #4a4030;
  box-shadow: none;
}

body.lamp-off .prop-note { filter: brightness(0.55) saturate(0.7); transition: filter 0.7s; }

body.lamp-off .mug-steam { opacity: 0.35; }

body.lamp-off .topbar::before { opacity: 0.15; transition: opacity 0.7s; }

body.lamp-off .topnav a.active {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    0 3px 8px rgba(0, 0, 0, 0.3);
}

/* ---------- responsive ---------- */

@media (max-width: 1180px) {
  .desk-lamp { transform: scale(0.82); transform-origin: 0 100%; left: 1%; }
  .prop-phone, .prop-driver { display: none; }
}

@media (max-width: 980px) {
  .topnav a { padding: 0 11px 2px; font-size: 13px; }
  .prop-mouse, .prop-mug { display: none; }
  .prop-note { right: 2%; top: 16%; }
  .desk-scene { min-height: 560px; }
  .tiles { gap: 11px; }
  .tile { min-height: 84px; }
}

@media (max-width: 760px) {
  .topbar { height: auto; flex-wrap: wrap; padding: 10px 14px; row-gap: 8px; }
  .topnav { margin-left: 0; width: 100%; order: 3; overflow-x: auto; }
  .topnav a { margin-bottom: 0; height: 32px; flex: 1 0 auto; justify-content: center; }
  .globalsearch { margin-left: 0; flex: 1 1 200px; }
  .desktop { top: 0; }
  .desk-scene { min-height: 0; padding-bottom: 24px; }
  .desk-lamp, .lamp-cone, .lamp-pool, .desk-props { display: none; }
  .desk-surface { top: 12%; }
  .keyboard { width: 100%; transform: none; margin-top: 10px; }
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .kb-chrome { display: none; }
  .dash-hero { padding-top: 14px; }
}

/* ---------- reduced motion: hold the lamp steady ---------- */

@media (prefers-reduced-motion: reduce) {
  .lamp-cone, .lamp-pool, .lamp-bulb, .mug-steam, .kb-leds i:last-child {
    animation: none;
  }
}

/* ===========================================================================
   SCENE + POLISH — the three.js backdrop (web/js/scene.js) and the glass /
   glow finish layered over the desk theme. Everything here degrades cleanly:
   without WebGL the original CSS backgrounds are used (.has-scene is only
   set once the canvas exists).
   =========================================================================== */

html { background: #07080c; min-height: 100%; }

#scene-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  display: block;
}

html.has-scene body { background: transparent; }
html.has-scene body { min-height: 100vh; }

/* ---------- page entrance ---------- */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

#page > .page > * { animation: rise-in 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
#page > .page > *:nth-child(2) { animation-delay: 0.05s; }
#page > .page > *:nth-child(3) { animation-delay: 0.10s; }
#page > .page > *:nth-child(4) { animation-delay: 0.15s; }
#page > .page > *:nth-child(n+5) { animation-delay: 0.2s; }

/* ---------- topbar: lamp-lit folder, now translucent ---------- */

html.has-scene .topbar {
  background:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.04) 0 1px, transparent 1px 4px),
    linear-gradient(180deg, rgba(86, 68, 40, 0.88) 0%, rgba(52, 41, 24, 0.9) 12%, rgba(30, 24, 15, 0.92) 100%);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.45), 0 1px 0 rgba(255, 190, 100, 0.06);
}

.brand {
  background: linear-gradient(180deg, #2c2313, #1b150a);
  text-shadow: 0 0 14px rgba(255, 195, 97, 0.35);
}

/* ---------- glass surfaces ---------- */

html.has-scene .card,
html.has-scene .table-wrap {
  background: linear-gradient(180deg, rgba(32, 38, 54, 0.72) 0%, rgba(20, 24, 34, 0.74) 100%);
  border-color: rgba(255, 255, 255, 0.07);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 18px 44px rgba(0, 0, 0, 0.38);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
}

html.has-scene .table-wrap { border-radius: 12px; }

html.has-scene .status-card {
  background: linear-gradient(180deg, rgba(40, 47, 66, 0.78), rgba(24, 28, 40, 0.8));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: transform 0.18s, border-color 0.18s, box-shadow 0.18s;
}

html.has-scene .status-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4), 0 0 22px rgba(232, 162, 61, 0.12);
}

.data-table tbody tr { transition: background 0.15s; }
.data-table tbody tr:hover { background: rgba(232, 162, 61, 0.07); }

.page-head h1 {
  background: linear-gradient(180deg, #fff6e0, #e8cfa0);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  letter-spacing: -0.3px;
}

/* ---------- desk: let the room breathe through ---------- */

html.has-scene .desk-room {
  background:
    radial-gradient(420px 300px at 92% 12%, rgba(140, 160, 200, 0.06), transparent 70%),
    linear-gradient(180deg, rgba(14, 16, 23, 0.55) 0%, rgba(10, 12, 18, 0.7) 46%, rgba(7, 8, 12, 0.88) 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}

/* ---------- login ---------- */

html.has-scene body.login-body {
  background: transparent;
  justify-content: center;
}

@media (min-width: 900px) {
  html.has-scene body.login-body { justify-content: flex-end; padding-right: 13vw; }
}

.login-card {
  position: relative;
  background: linear-gradient(160deg, rgba(38, 45, 64, 0.62), rgba(18, 21, 31, 0.72));
  border: 1px solid rgba(255, 255, 255, 0.09);
  backdrop-filter: blur(22px) saturate(1.3);
  -webkit-backdrop-filter: blur(22px) saturate(1.3);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 40px 90px rgba(0, 0, 0, 0.6),
    0 0 80px rgba(232, 162, 61, 0.10);
  animation: rise-in 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* amber light catching the card's top-left corner */
.login-card::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255, 195, 97, 0.65), transparent 38%, transparent 70%, rgba(126, 162, 255, 0.3));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.login-brand {
  font-size: 24px;
  background: none;
  border: 0;
  box-shadow: none;
  text-shadow: 0 0 22px rgba(255, 195, 97, 0.4);
}

.login-card input {
  background: rgba(8, 10, 16, 0.6);
}

@media (prefers-reduced-motion: reduce) {
  #page > .page > *, .login-card { animation: none; }
}

/* ---------- 3D desk (web/js/desk3d.js) ----------
   The canvas replaces the CSS-built desk, lamp and props; the keypad stays
   HTML on top. If WebGL is missing, .is-3d is never set and the CSS desk shows. */

.desk3d-canvas {
  position: absolute;
  left: -40px;
  top: -28px;
  width: calc(100% + 80px);
  height: calc(100% + 28px);
  z-index: 1;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.desk-scene.is-3d { --lamp-lit: 1; }

.desk-scene.is-3d .desk-room,
.desk-scene.is-3d .desk-surface,
.desk-scene.is-3d .lamp-pool,
.desk-scene.is-3d .desk-lamp,
.desk-scene.is-3d .desk-props { display: none; }

/* the keypad isn't part of the 3D scene, so the lamp's glow is washed over its
   left edge in CSS instead of the old hard-edged cone */
.desk-scene.is-3d .lamp-cone {
  left: -4%;
  top: 14%;
  width: 62%;
  height: 80%;
  clip-path: none;
  filter: none;
  animation: none;
  opacity: var(--lamp-lit);
  background: radial-gradient(ellipse 60% 55% at 16% 38%, rgba(255, 200, 120, 0.16), rgba(255, 190, 100, 0.05) 55%, transparent 80%);
}

.desk-scene.is-3d .kb-plate { box-shadow:
  inset 0 1px 0 rgba(255, 255, 255, 0.09),
  inset 0 -3px 8px rgba(0, 0, 0, 0.5),
  0 3px 0 #0a0c11,
  0 30px 40px -8px rgba(0, 0, 0, 0.7),
  0 50px 90px rgba(0, 0, 0, 0.55); }

/* ---------- bigger dashboard + keycaps with a life story ----------
   Intake is the most-pressed key: dulled, scuffed, grimy at the edges and
   polished smooth in the middle. Pickup is lightly worn. The rest are new. */

.desk-page { max-width: 1560px; padding-left: 16px; padding-right: 16px; }
.desk-scene { min-height: 720px; }
.keyboard { width: min(930px, 96%); margin-top: 8px; }
.desk-scene.is-3d .kb-hint { display: none; }
.kb-plate { padding: 34px 32px 24px; border-radius: 22px; }

.tiles {
  grid-template-columns: repeat(6, 1fr);
  gap: 16px 18px;
}

.tile-wide { grid-column: span 3; }
.tile-mid { grid-column: span 2; }

.tile {
  align-items: center;
  justify-content: center;
  min-height: 108px;
  padding: 14px;
  border-radius: 12px;
  overflow: hidden;
  isolation: isolate;
}

.tile-primary { min-height: 132px; }

.tile-title {
  font-size: 19px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-align: center;
}

.tile-primary .tile-title { font-size: 25px; letter-spacing: 1px; }

/* ----- physical keys -----
   Each key is a switch well cut into the plate (.tile) holding a keycap
   (.tile-cap): a tapered body with a visible front wall, and a slightly
   dished top face (::before) that carries the legend. Wear lives on the face
   (::after). Pressing sinks the cap into the well. */

.tiles .tile,
.tiles .tile:hover:not(:disabled),
.tiles .tile:active:not(:disabled) {
  display: block;
  padding: 6px 6px 4px;
  min-height: 98px;
  border-radius: 15px;
  border: 1px solid #020304;
  background: linear-gradient(180deg, #05070a, #0b0e14);
  box-shadow:
    inset 0 4px 10px rgba(0, 0, 0, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.05),
    0 1px 0 rgba(255, 255, 255, 0.06);
  transform: none;
  filter: none;
  overflow: visible;
  isolation: auto;
}

.tiles .tile.tile-primary { min-height: 120px; }

.tile-cap {
  --wall: #0c0f16;
  --wall-hi: #323a4d;
  --wall-lo: #1b2030;
  --face-a: #424b60;
  --face-b: #2e3547;
  --face-c: #3a4256;
  --legend: #eef1f7;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  min-height: inherit;
  box-sizing: border-box;
  padding-bottom: 8px;
  border-radius: 12px;
  background: linear-gradient(180deg, var(--wall-hi) 0%, var(--wall-lo) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 6px 0 var(--wall),
    0 10px 10px rgba(0, 0, 0, 0.7);
  transform: translateY(-3px);
  transition: transform 0.07s ease, box-shadow 0.07s ease, filter 0.14s ease;
}

/* dished top face, narrower toward the back like a real cap */
.tile-cap::before {
  content: "";
  position: absolute;
  inset: 6px 9px 15px;
  border-radius: 9px 9px 10px 10px;
  background:
    radial-gradient(90% 70% at 50% 120%, rgba(255, 255, 255, 0.10), transparent 70%),
    linear-gradient(180deg, var(--face-a) 0%, var(--face-b) 55%, var(--face-c) 100%);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.28),
    inset 0 -2px 4px rgba(0, 0, 0, 0.35),
    inset 3px 0 5px rgba(0, 0, 0, 0.18),
    inset -3px 0 5px rgba(0, 0, 0, 0.18),
    0 -1px 0 rgba(0, 0, 0, 0.4);
}

.tile-cap::after {
  content: "";
  position: absolute;
  inset: 6px 9px 15px;
  border-radius: 9px 9px 10px 10px;
  pointer-events: none;
}

.tile-cap .tile-title {
  position: relative;
  z-index: 1;
  margin-top: -6px;
  color: var(--legend);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.55), 0 1px 0 rgba(255, 255, 255, 0.08);
}

.tile:hover:not(:disabled) .tile-cap { filter: brightness(1.12); transform: translateY(-4px); }

.tile:active:not(:disabled) .tile-cap {
  transform: translateY(2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.15),
    0 2px 0 var(--wall),
    0 3px 5px rgba(0, 0, 0, 0.6);
}

.tile:focus-visible { outline: 2px solid var(--accent-bright); outline-offset: 3px; }

/* ----- new graphite keys: a gloss band across the top of the face ----- */

.tile:not(.tile-primary) .tile-cap::after {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0) 42%);
}

/* ----- pickup: lightly worn amber ----- */

.tile-pickup .tile-cap {
  --wall: #6a430c;
  --wall-hi: #e1a038;
  --wall-lo: #a56a17;
  --face-a: #ffd072;
  --face-b: #eaa73f;
  --face-c: #f2b24c;
  --legend: #2e1c05;
}

.tile-pickup .tile-cap::after {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='120'%3E%3Cg stroke='%23fff3d6' stroke-width='.7' opacity='.55' fill='none'%3E%3Cpath d='M20 90 L78 72'/%3E%3Cpath d='M130 30 L170 44'/%3E%3C/g%3E%3Cg stroke='%234a2b05' stroke-width='.6' opacity='.35'%3E%3Cpath d='M44 20 L66 31'/%3E%3C/g%3E%3C/svg%3E") center / 100% 100%,
    radial-gradient(60% 70% at 50% 42%, rgba(255, 244, 210, 0.25), transparent 70%),
    radial-gradient(120% 100% at 50% 50%, transparent 64%, rgba(85, 48, 8, 0.25) 100%);
}

/* ----- intake: well-worn amber ----- */

.tile-intake .tile-cap {
  --wall: #4f3309;
  --wall-hi: #b5812e;
  --wall-lo: #7d5216;
  --face-a: #d9a448;
  --face-b: #bf8429;
  --face-c: #c8923a;
  --legend: #3a2305;
}

.tile-intake .tile-cap::after {
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='132'%3E%3Cg stroke='%23fff0cc' stroke-width='.8' opacity='.6' fill='none'%3E%3Cpath d='M14 104 L96 70'/%3E%3Cpath d='M30 112 L70 96'/%3E%3Cpath d='M150 24 L226 58'/%3E%3Cpath d='M170 18 L200 30'/%3E%3Cpath d='M118 112 L164 92'/%3E%3Cpath d='M60 18 L84 26'/%3E%3C/g%3E%3Cg stroke='%233a2104' stroke-width='.8' opacity='.5' fill='none'%3E%3Cpath d='M40 40 L110 58'/%3E%3Cpath d='M176 96 L228 84'/%3E%3Cpath d='M98 14 L130 40'/%3E%3C/g%3E%3C/svg%3E") center / 100% 100%,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .16  0 0 0 0 .09  0 0 0 0 .02  0 0 0 -2.2 1.35'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 180px 180px,
    radial-gradient(50% 60% at 50% 46%, rgba(255, 226, 160, 0.30), transparent 72%),
    radial-gradient(14px 10px at 3px 2px, rgba(20, 12, 4, 0.95) 55%, transparent 62%),
    radial-gradient(110% 95% at 50% 46%, transparent 50%, rgba(52, 28, 4, 0.55) 100%);
  opacity: 0.7;
}

.tile-intake .tile-title { opacity: 0.92; text-shadow: 0 1px 0 rgba(255, 226, 160, 0.25); }

@media (max-width: 760px) {
  .tiles { grid-template-columns: repeat(2, 1fr); }
  .tile-wide, .tile-mid { grid-column: span 1; }
  .tile-primary { min-height: 108px; }
  .tile-primary .tile-title { font-size: 21px; }
}

/* ----- customer picker: quiet Change + linked name -----
   Changing the customer on an open ticket is rare, so the Change button
   drops the keycap chrome and reads as quiet text (both hosts: the intake
   window and the ticket page — same widget, same look). These rules sit
   after the .btn keycap blocks on purpose: equal-specificity overrides. */
.cust-change {
  border: 0;
  background: transparent;
  box-shadow: none;
  padding: 2px 6px;
  color: var(--muted);
  text-shadow: none;
}
.cust-change:hover:not(:disabled) {
  color: var(--accent);
  transform: none;
  filter: none;
  box-shadow: none;
}
.cust-change:active:not(:disabled) { transform: none; box-shadow: none; }

/* The selected customer's name links to their page (ticket page): bold like
   the plain text it replaces, with the accent on hover to invite the click. */
a.cust-selected-name { font-weight: 700; }
a.cust-selected-name:hover { color: var(--accent); }

/* ----- contract window -----
   Preview fills the window below the actions row; the stored document
   (HTML or PDF) renders in the iframe. */
.contract-view {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
}
.cv-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
}
.cv-meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cv-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.cv-frame {
  flex: 1;
  min-height: 0;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
}
