/* IO Studio — minimal, matches the studio's black/white identity. */

/* Bundled so the app looks the same on any machine, installed font or not. */
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Regular.otf') format('opentype');
  font-weight: 400; font-style: normal; font-display: block;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Italic.otf') format('opentype');
  font-weight: 400; font-style: italic; font-display: block;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Medium.otf') format('opentype');
  font-weight: 500; font-style: normal; font-display: block;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Semibold.otf') format('opentype');
  font-weight: 600; font-style: normal; font-display: block;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Bold.otf') format('opentype');
  font-weight: 700; font-style: normal; font-display: block;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fonts/GeneralSans-Light.otf') format('opentype');
  font-weight: 300; font-style: normal; font-display: block;
}

:root {
  /* tells the engine which way to render its own widgets: the date picker
     popup, the calendar icon, dropdown lists and scrollbars */
  color-scheme: light;
  --ink: #111214;
  --ink-2: #3d4046;
  --muted: #7b8087;
  --faint: #a0a5ab;
  --line: #d7dad9;
  --line-2: #dfe2e1;
  --bg: #e3e6e5;
  --panel: #e8eae9;
  --panel-2: #edefee;
  --sidebar: #dbdedd;
  --accent: #111214;
  --green: #1f7a4d;
  --green-bg: #dfeee6;
  --amber: #8a5a00;
  --amber-bg: #f6ead2;
  --red: #a32020;
  --red-bg: #f4e0e0;
  --hover: #eef0ef;
  --line-strong: #c4c8c7;
  --on-accent: #ffffff;
  --accent-hover: #000000;
  --track: #d9dcdb;
  --radius: 12px;
  --shadow: -6px -6px 16px #ffffff, 10px 10px 26px rgba(13,39,80,.10);

  /* Soft-UI light and shade. The panel sits on the same plane as the page,
     so depth comes only from these two shadows: a white highlight up-left
     and a cool shade down-right. */
  --neu-light: #ffffff;
  --neu-dark: rgba(13, 39, 80, .20);
  --raised: -5px -5px 12px var(--neu-light), 6px 6px 14px var(--neu-dark);
  --raised-sm: -3px -3px 7px var(--neu-light), 4px 4px 9px var(--neu-dark);
  --raised-lift: -7px -7px 16px var(--neu-light), 9px 9px 19px var(--neu-dark);
  --pressed: inset -4px -4px 9px rgba(255,255,255,.92),
             inset 5px 5px 12px rgba(13,39,80,.24);
  --pressed-sm: inset -3px -3px 6px rgba(255,255,255,.9),
                inset 3px 3px 7px rgba(13,39,80,.20);
  --card-shadow: none;
  --sunken: inset 3px 3px 7px rgba(13,39,80,.17), inset -3px -3px 7px rgba(255,255,255,.95);
  --sunken-focus: inset 4px 4px 10px rgba(13,39,80,.24), inset -3px -3px 8px rgba(255,255,255,1);

  /* light mode carries no hard edges — the shadows do that work */
  --btn-border: transparent;
  --card-border: var(--line);
  --input-border: transparent;
  --input-bg: var(--bg);
  /* selected states are grooves here, filled pills in dark */
  --nav-on-bg: transparent;
  --nav-on-ink: var(--ink);
  --seg-on-bg: transparent;
  --seg-on-ink: var(--ink);
  /* the main action reads as a bright key lifted off the surface, not a
     black slab — a solid black fill fights the soft relief */
  --primary-bg: #ffffff;
  --primary-ink: var(--ink);
}

/* Dark theme, same soft UI. A near-black page cannot show relief — there is
   nothing for the highlight to be lighter than — so the planes are lifted to
   charcoal and the highlight becomes a faint lightening rather than white. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --ink: #eceef2;
  --ink-2: #c5c9d1;
  --muted: #969ba5;
  --faint: #7c828c;
  --line: #31353c;
  --line-2: #2a2e34;
  --bg: #1e2126;
  --panel: #23262c;
  --panel-2: #282c33;
  --sidebar: #191c21;
  --accent: #eceef2;
  --on-accent: #1a1c20;
  --accent-hover: #ffffff;
  --hover: #292d34;
  --line-strong: #454a53;
  --track: #2e323a;
  --green: #5fd39b;
  --green-bg: #1a3226;
  --amber: #e3b262;
  --amber-bg: #35291a;
  --red: #f08a8a;
  --red-bg: #3a1e20;

  --neu-light: rgba(255, 255, 255, .055);
  --neu-dark: rgba(0, 0, 0, .55);
  --raised: -5px -5px 12px var(--neu-light), 6px 6px 14px var(--neu-dark);
  --raised-sm: -3px -3px 7px var(--neu-light), 4px 4px 9px var(--neu-dark);
  --raised-lift: -7px -7px 16px rgba(255,255,255,.075), 9px 9px 19px rgba(0,0,0,.6);
  --pressed: inset -4px -4px 9px rgba(255,255,255,.05),
             inset 5px 5px 12px rgba(0,0,0,.6);
  --pressed-sm: inset -3px -3px 6px rgba(255,255,255,.045),
                inset 3px 3px 7px rgba(0,0,0,.55);
  --sunken: inset 3px 3px 7px rgba(0,0,0,.5), inset -3px -3px 7px rgba(255,255,255,.045);
  --sunken-focus: inset 4px 4px 10px rgba(0,0,0,.65), inset -3px -3px 8px rgba(255,255,255,.06);
  --shadow: -6px -6px 16px rgba(255,255,255,.04), 12px 12px 30px rgba(0,0,0,.6);

  /* information panels stay flat here too */
  --card-shadow: none;
  --card-border: var(--line);
  --btn-border: transparent;
  --input-border: transparent;
  --input-bg: var(--bg);
  --nav-on-bg: transparent;
  --nav-on-ink: var(--ink);
  --seg-on-bg: transparent;
  --seg-on-ink: var(--ink);
  --primary-bg: #14171b;
  --primary-ink: var(--ink);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.5 'General Sans', "Segoe UI", -apple-system, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -.01em; }

/* ---------------------------------------------------------------- layout */

.app { display: flex; min-height: 100%; }

.sidebar {
  width: 232px;
  flex: 0 0 232px;
  background: var(--sidebar);
  border-right: 1px solid var(--line);
  padding: 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; padding: 8px 4px 14px;
  width: 100%; border: none; background: none; color: inherit;
  font: inherit; cursor: pointer;
}
.brand:hover img { transform: scale(1.03); }
.brand img { transition: transform .18s ease; }
.brand img { width: 78px; height: 78px; }
/* dark theme: the mark is black artwork, so invert it rather than ship a copy */
:root[data-theme="dark"] .brand img { filter: invert(1) brightness(1.15); }
.wordmark { font-size: 15px; letter-spacing: .16em; white-space: nowrap; }
.wordmark b { font-weight: 700; }
.wordmark span { font-weight: 300; margin-left: .32em; }

#nav { display: flex; flex-direction: column; gap: 2px; }

.nav-group-head {
  width: 100%;
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px;
  border: none; background: none; border-radius: 8px;
  font: inherit; font-size: 13.5px; font-weight: 600; color: var(--ink);
  cursor: pointer; text-align: left;
}
/* An open section and its submenu share one hollow: the groove sits on the
   group itself and wraps both. */
.nav-group {
  border-radius: 12px;
  padding: 5px;
  transition: box-shadow .18s ease;
}
.nav-group.open { box-shadow: var(--sunken); }
.nav-group.open > .nav-group-head { color: var(--ink); }

.nav-group-head:hover { background: var(--hover); }
/* shared disclosure arrow: points right when closed, down when open */
.chev {
  width: 7px; height: 7px; flex: 0 0 7px;
  border-right: 1.6px solid var(--faint);
  border-bottom: 1.6px solid var(--faint);
  transform: rotate(-45deg);
  transition: transform .18s ease;
}
.nav-group-head .chev { margin-left: auto; }
.nav-group.open .nav-group-head .chev { transform: rotate(45deg); }

/* max-height rather than the 0fr/1fr grid trick — one property, no inner
   wrapper needed. The cap only has to exceed the tallest submenu. */
.nav-group-items {
  max-height: 0;
  overflow: hidden;
  transition: max-height .22s ease;
}
.nav-group.open .nav-group-items { max-height: 340px; }
/* no second groove here — the group above already provides it */
.nav-group-items > div { overflow: hidden; }
.nav-group-items a {
  display: block;
  margin: 2px 0;
  padding: 7px 11px 7px 15px;
  border-radius: 8px;
  color: var(--ink-2);
  font-size: 13.5px;
}
.nav-group-items a:hover { background: var(--hover); }
.nav-group-items a.active {
  background: var(--nav-on-bg); color: var(--nav-on-ink);
  box-shadow: var(--pressed-sm); font-weight: 600;
}

.nav-single {
  padding: 8px 11px;
  border-radius: 7px;
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 600;
}
.nav-single:hover { background: var(--bg); }
.nav-single.active {
  background: var(--nav-on-bg); color: var(--nav-on-ink);
  box-shadow: var(--pressed-sm);
}

/* the switch is the last thing in the rail; the sidebar's own padding gives
   it the same breathing room at the bottom as the brand has at the top */
.sidebar-foot { margin-top: auto; }

main {
  flex: 1;
  min-width: 0;
  padding: 30px 34px 70px;
}

.loading { color: var(--muted); padding: 40px 0; }

/* ---------------------------------------------------------------- header */

/* Every page header is built the same: title hard against the left margin,
   controls hard against the right, all of them one fixed height so the title
   never shifts up or down depending on what sits opposite it. */
.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  min-height: 58px;
  margin-bottom: 22px;
}
.page-head h1 { font-size: 23px; }
.page-head .sub { color: var(--muted); font-size: 13px; margin-top: 3px; }
.page-head .actions { display: flex; gap: 9px; align-items: center; }

.page-head .actions .btn,
.page-head .actions .segmented,
.page-head .actions input,
.page-head .actions .sel-btn {
  height: 46px;
  font-size: 14.4px;
  border-radius: 11px;
}
.page-head .actions .btn { padding: 0 20px; }
/* one width for every "New …" action, so they line up from page to page */
.page-head .actions .btn-primary { min-width: 158px; }
.page-head .actions input { width: 240px; }
.page-head .actions .sel { width: 190px; }
.page-head .actions .segmented button { height: 100%; padding: 0 15px; }

/* --------------------------------------------------------------- buttons */

.btn {
  border: 1px solid var(--btn-border);
  background: var(--panel);
  color: var(--ink);
  padding: 9px 16px;
  border-radius: 9px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--raised);
  transition: box-shadow .13s ease, background .12s, color .12s, transform .06s;
  white-space: nowrap;
}
.btn:hover { box-shadow: var(--raised-lift); background: var(--hover); }
/* held down: the surface sinks into the page */
.btn:active { box-shadow: var(--pressed); transform: translateY(1px); }

.btn-primary {
  background: var(--primary-bg); border-color: var(--btn-border);
  color: var(--primary-ink); font-weight: 600;
}
.btn-primary:hover { background: var(--primary-bg); box-shadow: var(--raised-lift); }
.btn-primary:active { box-shadow: var(--pressed); }

.btn-block { width: 100%; }
.btn-sm { padding: 6px 11px; font-size: 12.5px; border-radius: 8px; box-shadow: var(--raised-sm); }
.btn-sm:hover { box-shadow: var(--raised); }
.btn-sm:active { box-shadow: var(--pressed-sm); }
.btn-danger { color: var(--red); }
.btn-danger:hover { background: var(--red-bg); }
.btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: var(--raised-sm); }

.icon-btn {
  border: none; background: none; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--muted); padding: 4px 6px;
  border-radius: 6px;
}
.icon-btn:hover { background: var(--bg); color: var(--ink); }

.link-btn {
  border: none; background: none; padding: 0; cursor: pointer;
  color: var(--muted); font: inherit; font-size: 12.5px; text-decoration: underline;
  text-underline-offset: 2px;
}
.link-btn:hover { color: var(--ink); }

/* ----------------------------------------------------------------- cards */

.card {
  background: var(--panel);
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  box-shadow: var(--card-shadow);
}
.card + .card { margin-top: 16px; }
.card-head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-2);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.card-head h3 { font-size: 14px; }
.card-body { padding: 18px; }

/* Collapsible card (Settings sections). Same shape as the sidebar groups:
   folded is the base state and .open expands. */
.card.collapsible > .card-head { cursor: pointer; user-select: none; }
.card.collapsible > .card-head:hover { background: var(--hover); }
.card.collapsible:not(.open) > .card-head { border-bottom: none; }
.card.collapsible.open > .card-head .chev { transform: rotate(45deg); }

/* inputs stay in the DOM while folded, so Save still reads every field.
   Same max-height approach as the sidebar. The cap must clear the tallest
   settings section. */
.card-fold {
  max-height: 0;
  overflow: hidden;
  transition: max-height .25s ease;
}
.card.collapsible.open .card-fold { max-height: 900px; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 20px; }
.stat {
  background: var(--panel); border: 1px solid var(--card-border);
  border-radius: var(--radius); padding: 15px 17px;
  box-shadow: var(--card-shadow);
}
.stat .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--faint); }
.stat .v { font-size: 20px; font-weight: 600; margin-top: 5px; letter-spacing: -.02em; }
.stat.is-red .v { color: var(--red); }
.stat.is-green .v { color: var(--green); }

/* ---------------------------------------------------------------- tables */

table { width: 100%; border-collapse: collapse; }
th {
  text-align: left; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .07em; color: var(--faint); font-weight: 600;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
}
td { padding: 12px 14px; border-bottom: 1px solid var(--line-2); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr.clickable { cursor: pointer; }
tbody tr.clickable:hover { background: var(--hover); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.mono { font-variant-numeric: tabular-nums; }
.t-strong { font-weight: 600; }
.t-muted { color: var(--muted); }
.t-small { font-size: 12.5px; }
.project-number {
  display: inline-block; min-width: 34px; margin-right: 8px;
  color: var(--faint); font-weight: 500; text-align: right;
}
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }

th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.th-label { display: inline-flex; align-items: center; }
th.sortable:hover { color: var(--muted); }
th.sortable.on { color: var(--ink); }
.sort-arrow {
  display: inline-block; width: 6px; height: 6px; margin-left: 6px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-135deg) translate(-1px, -1px);
  opacity: 0; transition: transform .15s ease, opacity .15s ease;
}
th.sortable.on .sort-arrow { opacity: 1; }
th.sortable.on .sort-arrow.down { transform: rotate(45deg) translate(-2px, -2px); }
table.projects td { vertical-align: middle; }
/* close the slack between the status badge and the Edit button */
table.projects th:nth-last-child(2),
table.projects td:nth-last-child(2) { padding-right: 2px; }
table.projects th:last-child,
table.projects td:last-child { padding-left: 2px; }

/* the number sits in its own narrow column now */
.badge.status-active { background: var(--green-bg); color: var(--green);
  border-color: color-mix(in srgb, var(--green) 35%, var(--line)); }
.badge.status-on_hold { background: var(--amber-bg); color: var(--amber);
  border-color: color-mix(in srgb, var(--amber) 35%, var(--line)); }
.badge.status-done { background: var(--bg); color: var(--muted); }

/* number narrow, name wide */
.project-head { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; }

/* Remove sits away from Save so it is never the button you hit by accident */
.modal-foot .btn-danger { margin-right: auto; }

.empty { padding: 46px 20px; text-align: center; color: var(--muted); }
.empty p { margin: 0 0 14px; }

/* ---------------------------------------------------------------- badges */

.badge {
  display: inline-block; padding: 3px 9px; border-radius: 20px;
  font-size: 11px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
  background: var(--bg); color: var(--muted); border: 1px solid var(--line);
}
.badge.draft { background: var(--bg); color: var(--muted); }
.badge.sent { background: var(--amber-bg); color: var(--amber);
  border-color: color-mix(in srgb, var(--amber) 35%, var(--line)); }
.badge.paid { background: var(--green-bg); color: var(--green);
  border-color: color-mix(in srgb, var(--green) 35%, var(--line)); }
.badge.overdue { background: var(--red-bg); color: var(--red);
  border-color: color-mix(in srgb, var(--red) 35%, var(--line)); }

/* ----------------------------------------------------------------- forms */

label { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--faint); margin-bottom: 5px; font-weight: 600; }
/* fields read as carved into the page, the opposite of a button */
input, select, textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--input-border);
  border-radius: 9px; font: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--input-bg);
  box-shadow: var(--sunken);
  transition: box-shadow .13s ease;
}
input:focus, select:focus, textarea:focus, .sel-btn:focus-visible {
  outline: none;
  border-color: var(--input-border);
  box-shadow: var(--sunken-focus);
}
textarea { resize: vertical; min-height: 62px; }
/* ------------------------------------------------------- select dropdown */

/* The engine draws a native list that no stylesheet can reach, so the real
   select is kept for its value and events while this stands in for it. */
.sel { position: relative; display: block; width: 100%; }
.sel select {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; pointer-events: none; margin: 0;
}
.sel-btn {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: 1px solid var(--input-border);
  border-radius: 9px; font: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--input-bg); box-shadow: var(--sunken);
  cursor: pointer; text-align: left;
  transition: box-shadow .13s ease;
}
.sel-btn span {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sel-btn i {
  width: 7px; height: 7px; flex: 0 0 7px; margin-right: 2px;
  border-right: 1.6px solid var(--faint);
  border-bottom: 1.6px solid var(--faint);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .16s ease;
}
.sel.open .sel-btn { box-shadow: var(--sunken-focus); }
.sel.open .sel-btn i { transform: rotate(-135deg) translate(-2px, -2px); }
.sel-btn.is-empty span { color: var(--muted); }

/* the list itself is fixed-position, so a modal's scrollbox cannot clip it */
.sel-pop {
  position: fixed; z-index: 90;
  background: var(--panel-2);
  border: 1px solid var(--card-border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 6px;
  max-height: 320px; overflow-y: auto;
}
.sel-opt {
  padding: 9px 12px; border-radius: 8px; font-size: 13.5px;
  color: var(--ink-2); cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sel-opt:hover, .sel-opt.cursor { background: var(--hover); color: var(--ink); }
.sel-opt.on { box-shadow: var(--pressed-sm); color: var(--ink); font-weight: 600; }

.field { margin-bottom: 14px; }
.field:last-child { margin-bottom: 0; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
/* city, state, postcode, country — the two short ones get only what they need */
.grid-place { display: grid; grid-template-columns: 1fr 70px 96px 1fr; gap: 12px; }
.hint { font-size: 11.5px; color: var(--faint); margin-top: 5px; text-transform: none; letter-spacing: 0; font-weight: 400; }

/* ---------------------------------------------------------------- editor */

/* wider right column so the date fields show a full date without truncating */
.editor { display: grid; grid-template-columns: minmax(0,1fr) 384px; gap: 18px; align-items: start; }
.editor-side { position: sticky; top: 30px; display: flex; flex-direction: column; gap: 16px; }

.presets { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  border: 1px solid var(--btn-border); background: var(--panel); border-radius: 20px;
  padding: 6px 13px; font: inherit; font-size: 12.5px; cursor: pointer; color: var(--ink-2);
  box-shadow: var(--raised-sm); transition: box-shadow .13s ease, color .12s;
}
.chip:active { box-shadow: var(--pressed-sm); }
.chip:hover { box-shadow: var(--raised); color: var(--ink); }
.chip .p { color: var(--faint); margin-left: 5px; font-size: 11.5px; }
.chip:hover .p { color: var(--muted); }

.items { display: flex; flex-direction: column; gap: 10px; }
/* The remove button sits in the top corner rather than taking a column, so
   the fields run out to the same right edge as the description below them. */
.item {
  border: 1px solid var(--card-border); border-radius: 10px;
  padding: 12px;
  background: var(--panel); position: relative;
}
.item-top { display: grid; grid-template-columns: minmax(0,1fr) 132px 66px 104px 112px; gap: 9px; align-items: end; }
/* the note and its Suggest key sit side by side; the box starts small and
   grows to fit whatever is typed, so it never needs a scrollbar of its own.
   The key is exactly as wide as the AMOUNT column it sits under. */
.desc { display: flex; align-items: flex-start; gap: 9px; margin-top: 9px; }
.desc textarea {
  flex: 1; min-width: 0;
  min-height: 40px; font-size: 13px; resize: none; overflow-y: hidden;
}
.suggest {
  flex: 0 0 112px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 40px; padding: 0;
  border: 1px solid var(--btn-border); border-radius: 9px;
  background: var(--panel); color: var(--muted);
  font: inherit; font-size: 12.5px; cursor: pointer; white-space: nowrap;
  box-shadow: var(--raised-sm); transition: box-shadow .13s ease, color .12s;
}
.suggest:hover { color: var(--ink); box-shadow: var(--raised); }
.suggest:active { box-shadow: var(--pressed-sm); }
.suggest:disabled { opacity: .6; cursor: default; }
.suggest .spark { width: 15px; height: 15px; flex: 0 0 15px; fill: currentColor; }
.item .amount {
  padding: 9px 12px; border-radius: 9px; background: var(--panel);
  box-shadow: var(--raised-sm);
  font-variant-numeric: tabular-nums; text-align: right; font-weight: 600; font-size: 13.5px;
  border: 1px solid var(--btn-border);
}
.item-del {
  position: absolute; top: 6px; right: 6px;
  font-size: 18px; line-height: 1;
}

.totals-row { display: flex; justify-content: space-between; padding: 7px 0; font-size: 13.5px; }
.totals-row.total {
  border-top: 1px solid var(--ink); margin-top: 6px; padding-top: 11px;
  font-size: 17px; font-weight: 600; letter-spacing: -.02em;
}
.totals-row .t-label { color: var(--muted); }

.side-actions { display: flex; flex-direction: column; gap: 8px; }


/* ---------------------------------------------------------------- modal */

.modal { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 26px; }
.modal[hidden] { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(17,18,20,.34); }
.modal-panel {
  position: relative; background: var(--panel-2); border-radius: 14px;
  box-shadow: var(--shadow); width: min(620px, 100%); max-height: 90vh;
  display: flex; flex-direction: column; overflow: hidden;
}
.modal-panel.wide { width: min(900px, 100%); height: 90vh; }
.modal-panel header {
  padding: 15px 18px; border-bottom: 1px solid var(--line-2);
  display: flex; align-items: center; justify-content: space-between;
}
.modal-panel header h2 { font-size: 15px; }
#modal-body { padding: 18px; overflow: auto; flex: 1; }
#modal-body.flush { padding: 0; }
#modal-body iframe { width: 100%; height: 100%; border: none; display: block; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* ---------------------------------------------------------------- toast */

.toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: var(--accent); color: var(--on-accent); padding: 10px 18px; border-radius: 8px;
  font-size: 13.5px; z-index: 90; box-shadow: var(--shadow);
}
.toast[hidden] { display: none; }
.toast.err { background: var(--red); color: #fff; }

/* ------------------------------------------------------------- dashboard */

.segmented {
  display: inline-flex; gap: 4px; padding: 5px;
  border: 1px solid var(--btn-border); border-radius: 13px;
  background: var(--panel); box-shadow: var(--sunken);
}
.segmented button {
  border: none; background: none; font: inherit; font-size: 13.8px;
  padding: 8px 14px; cursor: pointer; color: var(--muted); white-space: nowrap;
}
.segmented button { border-radius: 8px; transition: box-shadow .13s ease, color .12s; }
.segmented button:hover { color: var(--ink); }
.segmented button.on {
  background: var(--seg-on-bg); color: var(--seg-on-ink);
  box-shadow: var(--pressed-sm); font-weight: 600;
}

.stat .delta { font-size: 11.5px; margin-top: 4px; color: var(--muted); }
.stat .delta.up { color: var(--green); }
.stat .delta.down { color: var(--red); }

.alerts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.alert {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 16px; border-radius: var(--radius);
  border: 1px solid var(--card-border); background: var(--panel); font-size: 13px;
  box-shadow: var(--card-shadow);
}
.alert strong { font-size: 13px; }
.alert span { color: var(--muted); }
.alert .link-btn { margin-left: auto; }
.alert.bad { background: var(--red-bg); border-color: color-mix(in srgb, var(--red) 35%, var(--line)); }
.alert.bad strong { color: var(--red); }
.alert.warn { background: var(--amber-bg); border-color: color-mix(in srgb, var(--amber) 35%, var(--line)); }
.alert.warn strong { color: var(--amber); }
.alert.good { background: var(--green-bg); border-color: color-mix(in srgb, var(--green) 30%, var(--line)); }
.alert.good strong { color: var(--green); }

/* stretch, so the three cards end on the same line however tall each one is */
.dash-grid {
  display: grid; gap: 16px;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr);
  align-items: stretch;
}
.dash-grid .card + .card { margin-top: 0; }
.dash-grid .card { display: flex; flex-direction: column; }
.dash-grid .card-body { flex: 1; }
.dash-grid .ranks { height: 100%; justify-content: space-between; }

.chart { display: flex; flex-direction: column; gap: 0; }
.plot {
  display: flex; align-items: flex-end; gap: 6px; height: 168px;
  border-bottom: 1px solid var(--line);
}
.axis { display: flex; gap: 6px; padding-top: 8px; }
.chart.dense .plot, .chart.dense .axis { gap: 2px; }

.bar-wrap {
  flex: 1; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; justify-content: center;
}
.bar {
  width: 100%; max-width: 30px; border-radius: 4px 4px 0 0;
  background: var(--accent); opacity: .85; transition: opacity .12s;
}
.chart.dense .bar { max-width: none; border-radius: 2px 2px 0 0; }
.bar-wrap:hover .bar { opacity: 1; }
/* an empty period keeps its column so the spacing stays true, but draws
   nothing — the gap on the baseline says it plainly enough */
.bar.zero { background: none; height: 0; }

/* its own name on purpose: this used to be .tick, which the round sunken
   checkbox further down also answers to -- the axis dates were being drawn
   as dots */
.axis-label {
  flex: 1; min-width: 0;
  font-size: 10px; color: var(--faint); text-align: center; line-height: 1.25;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.axis-label span { display: block; opacity: .7; }

.sign-out {
  width: 100%; margin-top: 10px;
  display: flex; align-items: center; gap: 9px;
  padding: 9px 11px; border: none; border-radius: 9px;
  background: none; color: var(--muted); font: inherit; font-size: 13px;
  cursor: pointer; text-align: left;
}
.sign-out:hover { background: var(--hover); color: var(--ink); }
.sign-out svg { flex: 0 0 16px; }

/* ----------------------------------------------------------------- log in */

.login-page { display: grid; place-items: center; min-height: 100vh; padding: 24px; }
.login { width: 100%; max-width: 340px; }
.login-brand {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  margin-bottom: 30px;
}
.login-brand img { width: 114px; height: 114px; }
:root[data-theme="dark"] .login-brand img { filter: invert(1) brightness(1.15); }
.login-brand .wordmark { font-size: 15px; letter-spacing: .16em; }

.login-card {
  display: flex; flex-direction: column; gap: 10px;
  padding: 22px; border-radius: var(--radius);
  background: var(--panel); border: 1px solid var(--card-border);
}
.login-card label { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.login-card input { font-size: 16px; }
.login-card .btn { margin-top: 6px; height: 46px; }
.login-error { font-size: 12.5px; color: var(--red); }

/* a hairline with the word sitting in a gap, rather than a line and a word
   stacked on top of each other */
.login-or {
  display: flex; align-items: center; gap: 12px;
  margin: 16px 0 10px; color: var(--faint); font-size: 11.5px;
  text-transform: uppercase; letter-spacing: .08em;
}
.login-or::before, .login-or::after {
  content: ''; flex: 1; height: 1px; background: var(--line);
}
#pk-signin {
  width: 100%; display: inline-flex; align-items: center;
  justify-content: center; gap: 9px; margin-top: 0;
}

.passkeys { margin: 4px 18px 18px; }
.passkeys .t-label { margin-bottom: 8px; }
.passkey-list { list-style: none; margin: 0 0 12px; padding: 0; }
.passkey-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; margin-bottom: 6px;
  border-radius: 9px; background: var(--hover);
}
.passkey-list li > span:first-child { flex: 1; font-size: 13.5px; }

.sync-status {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  margin: 14px 18px 18px; padding: 12px 14px;
  border-radius: 10px; background: var(--hover);
}
.sync-status .ok { color: var(--green); }
.sync-status .warn { color: var(--red); }

.ranks { display: flex; flex-direction: column; gap: 13px; }
.rank-top { display: flex; justify-content: space-between; gap: 10px; font-size: 13px; }
.rank-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-track {
  height: 5px; border-radius: 3px; background: var(--track);
  margin: 5px 0 3px; overflow: hidden;
}
.rank-track div { height: 100%; background: var(--accent); border-radius: 3px; opacity: .8; }
.rank-sub { font-size: 11.5px; color: var(--faint); }

/* ----------------------------------------------------------------- tasks */

.tasks { display: flex; flex-direction: column; gap: 2px; }
.task { border-radius: 9px; }
.task + .task { border-top: 1px solid var(--line-2); }
.task-row { display: flex; align-items: center; gap: 12px; padding: 11px 4px; }
.task-row:hover { background: var(--hover); border-radius: 8px; }
.task-main { flex: 1; min-width: 0; }
.task-title { font-size: 14px; font-weight: 600; }
.task-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }
.task-meta .is-overdue { color: var(--red); font-weight: 600; }
.task.is-done .task-title { text-decoration: line-through; color: var(--muted); }

.tick {
  width: 20px; height: 20px; flex: 0 0 20px; padding: 0;
  border: 1px solid var(--btn-border); border-radius: 50%;
  background: var(--panel); cursor: pointer; position: relative;
  box-shadow: var(--sunken); transition: box-shadow .13s ease, background .12s;
}
.tick:hover { box-shadow: var(--raised-sm); }
.tick.on { background: var(--accent); box-shadow: var(--raised-sm); }
.tick.on::after {
  content: ''; position: absolute; left: 5px; top: 2px;
  width: 5px; height: 9px; border: solid var(--on-accent);
  border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.tick.small { width: 15px; height: 15px; flex-basis: 15px; }
.tick.small.on::after { left: 3.5px; top: 1px; width: 4px; height: 7px; border-width: 0 1.7px 1.7px 0; }

.subtasks { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .2s ease; }
.subtasks.open { grid-template-rows: 1fr; }
.subtasks > div { overflow: hidden; padding-left: 31px; }
.subtask { display: flex; align-items: center; gap: 10px; padding: 5px 4px; font-size: 13px; }
.subtask span { flex: 1; }
.subtask.is-done span { text-decoration: line-through; color: var(--muted); }
.subtask-add {
  margin: 6px 0 12px; width: min(420px, 100%);
  font-size: 13px; padding: 6px 10px;
}

.picks { display: flex; flex-direction: column; gap: 1px; }
.pick {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 8px; border-radius: 7px; cursor: pointer;
}
.pick:hover { background: var(--hover); }
.pick-main { flex: 1; min-width: 0; }
.pick-title { display: block; font-size: 13.5px; font-weight: 600; }
.pick-sub {
  display: block; font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* -------------------------------------------------------------- calendar */

.cal-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.cal-title { font-size: 17px; font-weight: 600; min-width: 190px; }

.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; }
.cal-dow {
  background: var(--panel); padding: 8px 10px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--faint); text-align: center;
}
.cal-day {
  background: var(--panel); min-height: 116px; padding: 7px 8px;
  display: flex; flex-direction: column; gap: 4px;
}
.cal-day.other { background: var(--bg); }
.cal-day.today .cal-num { background: var(--accent); color: var(--on-accent); }
.cal-num {
  align-self: flex-start; font-size: 12px; font-variant-numeric: tabular-nums;
  min-width: 21px; height: 21px; line-height: 21px; text-align: center;
  border-radius: 50%; color: var(--muted);
}
.cal-day.other .cal-num { opacity: .45; }
.cal-add {
  margin-top: auto; align-self: flex-start; border: none; background: none;
  color: var(--faint); font: inherit; font-size: 16px; line-height: 1;
  cursor: pointer; padding: 2px 5px; border-radius: 5px; opacity: 0;
}
.cal-day:hover .cal-add { opacity: 1; }
.cal-add:hover { background: var(--hover); color: var(--ink); }

.pill {
  font-size: 11.5px; padding: 3px 7px; border-radius: 5px; cursor: pointer;
  border: 1px solid transparent; text-align: left; width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  background: var(--hover); color: var(--ink-2); font-family: inherit;
}
.pill:hover { border-color: var(--line-strong); }
.pill.meeting { background: var(--amber-bg); color: var(--amber); }
.pill.call { background: var(--green-bg); color: var(--green); }
.pill.deadline { background: var(--red-bg); color: var(--red); }
.pill.task { background: var(--hover); color: var(--ink-2); border-color: var(--line); }
.pill.task.done { opacity: .5; text-decoration: line-through; }
.pill .dot { display: inline-block; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; margin-right: 5px; vertical-align: middle; }

.cal-list { display: flex; flex-direction: column; }
.cal-list-day { display: flex; gap: 18px; padding: 12px 4px; border-top: 1px solid var(--line-2); }
.cal-list-day:first-child { border-top: none; }
.cal-list-date { width: 116px; flex: 0 0 116px; font-size: 13px; }
.cal-list-date span { display: block; color: var(--faint); font-size: 11.5px; }
.cal-list-items { flex: 1; display: flex; flex-direction: column; gap: 5px; }
.cal-week { min-height: 320px; }

/* ---------------------------------------------------------- theme toggle */

/* Light: the switch is a raised key with a cold, unlit bulb.
   Dark: it is pressed into the surface and the bulb is burning, throwing warm
   light around the inside of the recess. */
.theme-toggle {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 11px; width: 100%;
  height: 46px; padding: 0 14px;
  border: 1px solid var(--btn-border); background: var(--panel); color: var(--ink);
  border-radius: 11px; font: inherit; font-size: 14px; font-weight: 500;
  cursor: pointer; margin-bottom: 0;
  box-shadow: var(--raised);
  transition: box-shadow .25s ease, color .25s ease, background .25s ease;
}
.theme-toggle:hover { box-shadow: var(--raised-lift); }
.theme-toggle:active { box-shadow: var(--pressed); }

.theme-toggle .bulb { display: flex; flex: 0 0 20px; position: relative; z-index: 1; }
.theme-toggle svg {
  width: 20px; height: 20px; fill: currentColor;
  transition: fill .25s ease, filter .25s ease;
}
.theme-toggle span:last-child { position: relative; z-index: 1; }

/* the pool of light spilling out of the bulb across the hollow */
.theme-toggle::before {
  content: ''; position: absolute; left: -26px; top: 50%;
  width: 150px; height: 150px; transform: translateY(-50%);
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 186, 92, .34) 0%,
    rgba(255, 172, 66, .17) 32%,
    rgba(255, 160, 50, .06) 55%,
    transparent 72%);
  opacity: 0; transition: opacity .3s ease;
  pointer-events: none;
}

:root[data-theme="dark"] .theme-toggle {
  box-shadow: var(--pressed);
  background: var(--bg);
  color: #f6d8a8;
}
:root[data-theme="dark"] .theme-toggle::before { opacity: 1; }
:root[data-theme="dark"] .theme-toggle svg {
  fill: #ffc775;
  filter: drop-shadow(0 0 5px rgba(255, 183, 77, .95))
          drop-shadow(0 0 13px rgba(255, 160, 40, .6))
          drop-shadow(0 0 26px rgba(255, 145, 25, .32));
}

@media (max-width: 1240px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

@media (max-width: 1080px) {
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
  .editor { grid-template-columns: 1fr; }
  .editor-side { position: static; }
  .item-top { grid-template-columns: 1fr 1fr; }
}

/* ----------------------------------------------------------------- phones */

/* The bar and the drawer exist in the markup at every width; only here do
   they come out of hiding. */
.topbar { display: none; }
.drawer-scrim { display: none; }

@media (max-width: 720px) {
  /* the notch and the home indicator, so nothing sits under either */
  .topbar {
    display: flex; align-items: center; gap: 12px;
    position: sticky; top: 0; z-index: 30;
    padding: max(8px, env(safe-area-inset-top)) 14px 8px;
    background: var(--sidebar);
    border-bottom: 1px solid var(--line);
  }
  .topbar .wordmark { font-size: 13px; }

  main { padding: 16px 14px calc(28px + env(safe-area-inset-bottom)); }

  /* the sidebar slides in over the page instead of taking a third of it */
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 40;
    height: 100%; width: 264px; flex-basis: 264px;
    transform: translateX(-100%);
    transition: transform .22s ease;
    overflow-y: auto;
    padding-top: max(22px, env(safe-area-inset-top));
  }
  .app.drawer-open .sidebar { transform: translateX(0); }
  .drawer-scrim {
    display: block; position: fixed; inset: 0; z-index: 35;
    background: rgba(0, 0, 0, .42);
    opacity: 0; transition: opacity .22s ease;
  }
  .app.drawer-open .drawer-scrim { opacity: 1; }
  .drawer-scrim[hidden] { display: none; }

  .page-head {
    flex-direction: column; align-items: stretch; gap: 12px;
    min-height: 0; margin-bottom: 18px;
  }
  .page-head h1 { font-size: 20px; }
  .page-head .actions { flex-wrap: wrap; }
  .page-head .actions > * { flex: 1 1 auto; min-width: 0; }
  /* five periods will not fit across a phone; let the row slide instead of
     letting the last one hang off the edge */
  .page-head .actions .segmented,
  .page-head .segmented {
    overflow-x: auto; max-width: 100%; justify-content: flex-start;
    scrollbar-width: none;
    /* the desktop rule pins this to 46px, which is shorter than the 44px
       touch targets plus its own padding -- the groove then cropped the
       bottom off every button */
    height: auto;
  }
  .page-head .segmented::-webkit-scrollbar { display: none; }
  .page-head .actions .segmented button,
  .page-head .segmented button { flex: 0 0 auto; height: auto; }

  /* a finger is not a mouse pointer: nothing tappable below 44px */
  .btn, .sel-btn, .segmented button { min-height: 44px; }
  /* Desktop field sizes are set for reading at desk distance with a mouse to
     aim; in the hand they are too small to read and to hit. Specific enough to
     beat the per-field sizes set further up. */
  input, select, textarea,
  .field input, .field select, .field textarea,
  .desc textarea, .item input, .item select { font-size: 15.5px; }

  .grid-2, .grid-3, .grid-place { grid-template-columns: 1fr; }
  .item-top { grid-template-columns: 1fr; }
  .desc { flex-direction: column; }
  /* stacked, the flex axis is vertical, so the `flex: 1` that made the box
     fill the width on a desktop would here fight the height being measured
     onto it -- hand the sizing back to the box itself */
  .desc textarea { flex: none; width: 100%; }
  .suggest { flex: 0 0 auto; width: 100%; }

  /* Wide tables scroll sideways inside their own card rather than pushing the
     whole page off the screen. The popup menus are attached to the body, not
     to the card, so nothing of theirs gets clipped by this. */
  .card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* Tables that stay tables slide sideways, wide enough that a name stays on
     one or two lines rather than stacking a word per row. The ones that turn
     into tiles below must be excluded by name -- a plain `.stacked` rule is
     the weaker selector and this one would quietly win, leaving a 780px tile
     in a 412px window. */
  .card table:not(.stacked) { min-width: 780px; }

  /* The invoice list is the one a phone actually gets used for, so it stops
     being a table here and becomes a stack of entries -- number and amount on
     the top line, client and status under it, the rest below. Eight columns
     across 375 pixels is not a table anyone can read. */
  /* the tiles below are panels in their own right, so the card around them
     steps back rather than putting a panel inside a panel */
  .card:has(table.invoices),
  .card:has(table.projects),
  .card:has(table.clients) {
    overflow-x: visible;
    background: none; border: none; box-shadow: none;
  }
  .stacked, .stacked tbody, .stacked tr, .stacked td { display: block; }
  .stacked { min-width: 0; width: 100%; }
  .stacked thead { display: none; }

  /* Each entry reads as its own tile: a raised panel with air around the text,
     and a gap between them. Stacked rows with only a hairline between them ran
     together on a phone -- three lines of one invoice looked like the tail of
     the one above it. */
  .stacked tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 3px 12px;
    padding: 15px 16px;
    margin-bottom: 11px;
    border: none;
    border-radius: 13px;
    background: var(--panel);
    box-shadow: var(--raised-sm);
  }
  .stacked tbody tr:last-child { margin-bottom: 2px; }
  .stacked tbody td { padding: 0; border: none; }
  .stacked td:empty { display: none; }
  .stacked .row-actions { display: flex; gap: 8px; }
  .stacked .row-actions .btn { flex: 1 1 0; }

  /* Which fact lands where. The left column carries what identifies the entry,
     the right column what you scan down the list for. */

  /* invoices: No. Client Project Issued Due Total Status  actions */
  table.invoices td:nth-child(1) { grid-area: 1 / 1; font-size: 15px; }  /* No.     */
  table.invoices td:nth-child(6) { grid-area: 1 / 2; text-align: right; }/* Total   */
  table.invoices td:nth-child(2) { grid-area: 2 / 1; }                   /* Client  */
  table.invoices td:nth-child(7) { grid-area: 2 / 2; text-align: right; }/* Status  */
  table.invoices td:nth-child(3) { grid-area: 3 / 1; }                   /* Project */
  table.invoices td:nth-child(4) { grid-area: 3 / 2; text-align: right; }/* Issued  */
  table.invoices td:nth-child(5) { display: none; }   /* due date: the badge already
                                                         says when one is overdue */
  table.invoices td:nth-child(8) { grid-area: 4 / 1 / auto / -1; margin-top: 10px; }

  /* projects: No. Project Location Client Invoices Billed Status  edit */
  table.projects td:nth-child(1) { grid-area: 1 / 1; font-size: 15px; }  /* No.      */
  table.projects td:nth-child(6) { grid-area: 1 / 2; text-align: right; }/* Billed   */
  table.projects td:nth-child(2) { grid-area: 2 / 1; font-size: 14px; }  /* Project  */
  table.projects td:nth-child(7) { grid-area: 2 / 2; text-align: right; }/* Status   */
  table.projects td:nth-child(3) { grid-area: 3 / 1 / auto / -1; }       /* Location */
  table.projects td:nth-child(4) { grid-area: 4 / 1; }                   /* Client   */
  table.projects td:nth-child(5) { grid-area: 4 / 2; text-align: right; }/* Invoices */
  table.projects td:nth-child(8) { grid-area: 5 / 1 / auto / -1; margin-top: 10px; }
  /* a bare number in the corner reads as nothing; say what it counts */
  table.projects td:nth-child(5)::before {
    content: 'Invoices '; color: var(--faint); font-size: 11.5px;
  }

  /* clients: Company Contact Location Email  actions
     Each on its own line: an American address runs to half a sentence, and
     sharing a row with it broke the contact's name across two lines. */
  table.clients td:nth-child(1) { grid-area: 1 / 1 / auto / -1; font-size: 15px; }
  table.clients td:nth-child(2) { grid-area: 2 / 1 / auto / -1; }        /* Contact  */
  table.clients td:nth-child(3) { grid-area: 3 / 1 / auto / -1; }        /* Location */
  table.clients td:nth-child(4) { grid-area: 4 / 1 / auto / -1; }        /* Email    */
  table.clients td:nth-child(5) { grid-area: 5 / 1 / auto / -1; margin-top: 10px; }

  .modal-panel {
    width: auto; max-width: none;
    inset: 10px 10px auto; max-height: calc(100vh - 20px);
    overflow-y: auto;
  }
  .modal-foot { flex-wrap: wrap; }
  .modal-foot .btn { flex: 1 1 130px; }
}
