:root {
  --border: #d7dee6;
  --ink: #1f2937;
  --muted: #6b7280;
  --accent: #2563eb;
  --bg: #f6f8fa;
  --panel: #ffffff;
  /* Light background shading used for opening/total/subtotal rows and
     primary-group heading rows -- its own variable (rather than the
     hardcoded #f8fafc/#f1f5f9 those rules used to carry individually)
     so the Display theme picker's palettes (further down this file)
     can each supply a shade that actually suits their own background,
     dark themes included. --shade-strong is the slightly heavier
     version .tb-primary-row wants. */
  --shade: #f8fafc;
  --shade-strong: #f1f5f9;
  /* Single source of truth for "grid heading text" size -- .grid th
     below reads it directly, and report letterheads/date lines
     reference it too (see trial_balance.html's print-only pieces) so
     "match the grid header" or "1pt above the grid header" always
     stays in sync with whatever this value actually is. */
  --grid-header-size: 0.8rem;
}

/* Display > Theme (base.html's topbar dropdown, wired up in
   display.py) -- swapping the handful of variables above is enough to
   re-skin nearly the whole app, since almost every rule in this file
   already reads them rather than a hardcoded color. "default" needs
   no block of its own: leaving data-theme unset (or set to "default")
   just leaves the plain :root values above in effect. Deliberately
   left alone: .btn-toolbar's warm-orange report-toolbar buttons (a
   fixed brand color, not part of the palette) and the Select Company
   window's own dark-backdrop styling (select_firm.html is a
   standalone page outside this shell, with no Display control on it
   at all). */
:root[data-theme="slate"] {
  --accent: #475569; --bg: #eef1f4; --panel: #ffffff; --ink: #1e293b;
  --muted: #64748b; --border: #d7dde5; --shade: #f1f4f7; --shade-strong: #e5e9ee;
}
:root[data-theme="forest"] {
  --accent: #15803d; --bg: #f3f8f3; --panel: #ffffff; --ink: #1c2b20;
  --muted: #5b6b60; --border: #d3e3d6; --shade: #eef6ef; --shade-strong: #dcebe0;
}
:root[data-theme="maroon"] {
  --accent: #9f1239; --bg: #fbf1f3; --panel: #ffffff; --ink: #3a1420;
  --muted: #7a5761; --border: #eccdd4; --shade: #fbeef1; --shade-strong: #f6dde3;
}
:root[data-theme="amber"] {
  --accent: #b45309; --bg: #fbf3e7; --panel: #fffdf8; --ink: #3a2a14;
  --muted: #8a7355; --border: #ecd9bb; --shade: #f8eedd; --shade-strong: #f1e2c6;
}
:root[data-theme="teal"] {
  --accent: #0e7490; --bg: #eef7f9; --panel: #ffffff; --ink: #132b30;
  --muted: #5b7d84; --border: #c9e4ea; --shade: #e7f4f6; --shade-strong: #d3ebef;
}
:root[data-theme="dark"] {
  --accent: #0ea5e9; --bg: #111827; --panel: #1a2333; --ink: #e5e9f0;
  --muted: #93a0b4; --border: #2c3a52; --shade: #202b3f; --shade-strong: #293650;
}
:root[data-theme="midnight"] {
  --accent: #8b5cf6; --bg: #0b0d17; --panel: #151726; --ink: #e6e3f5;
  --muted: #9089b0; --border: #2b2740; --shade: #1c1e33; --shade-strong: #262a45;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
}

/* Header -- layer 1 of the four-layer shell (Header / Dynamic Menu /
   Details / Footer). Only the Firm name gets real emphasis; the rest
   (city, crumb, FY range, Change Company) stays small so this never
   competes with the Details area for space. */
.topbar {
  padding: 10px 24px 8px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.topbar-row {
  display: flex;
  align-items: baseline;
  gap: 14px;
}
.topbar-subline { margin-top: 2px; }
.brand { font-weight: 600; font-size: 1.15rem; color: var(--ink); text-decoration: none; }
.crumb { color: var(--muted); font-size: 0.82em; }
.nav-context {
  margin-left: auto;
  font-size: 0.82em;
  color: var(--muted);
}
/* Dynamic Menu -- layer 2. Persistent on every client-facing screen
   (app.py's context processor builds nav_menu on every request), not
   just the landing page -- that was the actual gap: previously the
   menu only existed as the landing page's own content, so it
   disappeared the moment you opened any other screen. A top-level
   group with children opens as a <details> dropdown (native
   click-to-toggle + keyboard accessible, no JS needed); a top-level
   leaf is a direct link; a top-level separator becomes a vertical
   rule between groups, which actually means something in a horizontal
   bar (unlike the old boxed grid, where it was a no-op). */
.appnav {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
  padding: 4px 20px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  font-size: 0.88rem;
  position: relative;
}
.appnav-link {
  display: inline-block;
  padding: 8px 12px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
}
.appnav-link:hover { background: var(--bg); }
.appnav-link.menu-disabled:hover { background: none; }
.appnav-vrule { width: 1px; align-self: stretch; margin: 6px 8px; background: var(--border); }

.appnav-dropdown { position: relative; }
.appnav-dropdown > summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 6px;
  color: var(--ink);
}
.appnav-dropdown > summary::-webkit-details-marker { display: none; }
.appnav-dropdown > summary::after { content: " \25BE"; color: var(--muted); font-size: 0.8em; }
.appnav-dropdown:hover > summary,
.appnav-dropdown[open] > summary { background: var(--bg); }
.appnav-dropdown > .appnav-panel {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  min-width: 200px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.1);
  padding: 6px;
  margin-top: 2px;
}
.appnav-panel-list { list-style: none; margin: 0; padding: 0; }
.appnav-panel-list a,
.appnav-panel-list .menu-disabled {
  display: block;
  padding: 7px 10px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
  font-size: 0.9rem;
  white-space: nowrap;
}
.appnav-panel-list a:hover { background: var(--bg); }
/* A nested group (depth 3) inside a dropdown panel -- another
   <details>, indented, its own panel opening as a flush block rather
   than a second floating popup (keeps this to one level of overlay). */
.appnav-subdropdown { margin: 2px 0; }
.appnav-subdropdown > summary {
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 0.9rem;
}
.appnav-subdropdown > summary::after { content: " \25BE"; color: var(--muted); font-size: 0.8em; }
.appnav-subdropdown:hover > summary { background: var(--bg); }
.appnav-subdropdown > .appnav-panel {
  position: static;
  box-shadow: none;
  border: none;
  padding: 0 0 0 14px;
  margin: 0;
}
.appnav-separator-label {
  display: block;
  padding: 6px 10px 0;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}
.appnav-separator { border: none; border-top: 1px solid var(--border); margin: 4px 6px; }

/* Full width, same as pharma_platform's shell -- no centered max-width
   column. A Trial Balance / Day Book / Party-wise Sales style report
   genuinely wants the room; padding alone is enough of a side gutter. */
.content { padding: 24px; }

/* Footer -- layer 4. Version only, low emphasis, same idea as
   pharma_platform's footer (a single central version value, never
   hardcoded a second time). */
.app-footer {
  padding: 10px 24px;
  color: var(--muted);
  font-size: 0.75rem;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 18px 20px;
}

.panel-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}
.panel-head h1 { font-size: 1.15rem; margin: 0; }

/* Admin home screen (admin_app.py's index route / home.html) --
   deliberately blank apart from these entry-point cards, one per
   top-level admin section. Add more .home-card links here (not a
   dashboard widget) if the admin panel grows more sections. */
.home-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  padding: 40px 4px;
}
.home-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 240px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 22px 20px;
  text-decoration: none;
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.home-card:hover {
  border-color: var(--accent);
  box-shadow: 0 2px 10px rgba(15, 23, 42, 0.08);
}
.home-card-title { font-size: 1.05rem; font-weight: 600; }
.home-card-desc { font-size: 0.85rem; color: var(--muted); }

.grid { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.grid th, .grid td {
  text-align: left;
  padding: 9px 8px;
  border-bottom: 1px solid var(--border);
}
.grid th { color: var(--muted); font-weight: 600; font-size: var(--grid-header-size); text-transform: uppercase; letter-spacing: 0.02em; }
.grid .mono { font-variant-numeric: tabular-nums; color: var(--muted); }
.grid .empty { color: var(--muted); text-align: center; padding: 24px 0; }

.row-actions { white-space: nowrap; text-align: right; }
.inline { display: inline; }

.link {
  background: none; border: none; cursor: pointer;
  color: var(--accent); font-size: 0.88rem; padding: 0 4px;
}
.link:disabled { color: var(--border); cursor: default; }
.link-danger { color: #b91c1c; }

.tag { padding: 2px 8px; border-radius: 999px; font-size: 0.78rem; }
.tag-on { background: #dcfce7; color: #166534; }
.tag-off { background: #f3f4f6; color: #6b7280; }

.btn {
  border: 1px solid var(--border);
  background: var(--panel);
  padding: 7px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.88rem;
}
.btn-primary { background: var(--accent); border-color: var(--accent); color: white; }

.overlay {
  display: none;
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.35);
  align-items: center;
  justify-content: center;
}
.overlay.open { display: flex; }

.dialog {
  background: var(--panel);
  border-radius: 10px;
  padding: 22px 24px;
  width: 420px;
  max-width: 92vw;
  max-height: 88vh;
  overflow-y: auto;
}
.dialog h2 { margin: 0 0 14px; font-size: 1.05rem; }

.dialog label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 10px;
}
.dialog input[type="text"],
.dialog input[type="password"] {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--ink);
}
.row2 { display: flex; gap: 12px; }
.row2 label { flex: 1; }

/* Same field look as .dialog, for a form that's its own full page
   instead of a modal (e.g. client_form.html) -- a Client record is
   going to carry a lot more fields over time (GSTN, DL numbers, FSSAI
   numbers...) than a dialog comfortably holds. */
.form-page label {
  display: block;
  font-size: 0.82rem;
  color: var(--muted);
  margin-bottom: 14px;
}
.form-page input[type="text"],
.form-page input[type="password"],
.form-page select {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--ink);
  background: var(--panel);
}
.form-page { max-width: 640px; }

.checkbox { display: flex; align-items: center; gap: 6px; }
.checkbox input { width: auto; margin: 0; }

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 16px;
}

.flash { margin-bottom: 14px; }
.flash-msg {
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  color: #1e40af;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 0.88rem;
  margin-bottom: 6px;
}

.selector-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
  margin-bottom: 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.selector-form label {
  display: block;
  font-size: 0.78rem;
  color: var(--muted);
}
.selector-form select,
.selector-form input[type="date"] {
  display: block;
  margin-top: 4px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.88rem;
}

.grid .num { text-align: right; font-variant-numeric: tabular-nums; }
.grid .narration { color: var(--muted); font-size: 0.85em; margin-top: 2px; }
.grid .opening-row td, .grid .totals-row td { background: var(--shade); border-top: 2px solid var(--border); border-bottom: 2px solid var(--border); }

/* Day Book's Date column -- DD-MM-YYYY is a touch wider than the old
   YYYY-MM-DD, and a printed page is narrower than the screen needs to
   be, so without this the date wraps mid-string ("01-04-\n2007"),
   which reads badly next to a real printed report that never does
   that. */
.daybook-grid td:first-child, .daybook-grid th:first-child { white-space: nowrap; }

.notice {
  background: #fffbeb;
  border: 1px solid #fde68a;
  color: #92400e;
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 0.85rem;
  margin-bottom: 12px;
}

.clickable-row { cursor: pointer; }
.clickable-row:hover { background: var(--shade); }
.selected-row { background: #eff6ff; }

/* Devices screen (device_list.py) -- the current browser's own device
   code, and the Add-button/already-registered state device_list.html's
   own script toggles between. Plain shade box, not .notice's amber --
   this is informational, not a warning. */
.device-current {
  background: var(--shade);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 16px;
}
.device-current .device-uuid-value {
  font-size: 1rem;
  color: var(--ink);
  word-break: break-all;
  margin: 4px 0 10px;
}
.sub-head { font-size: 1rem; margin: 20px 0 10px; }
.grid.narrow { max-width: 420px; }

/* Toggle switch -- a real sliding on/off control (Sabari, 2026-09:
   "a slider"), not a plain checkbox, for any two-state field whose
   two sides both deserve an equally prominent label rather than one
   "this is ON" caption (Login Details' own Any Device/Approved Only
   is the first user of this). Built on a plain checkbox for real
   keyboard/form semantics -- .toggle-track/.toggle-thumb are just its
   visual skin, positioned as its own siblings (not children) so the
   `~` selector below can reach them from :checked. The checkbox
   itself is invisible but still occupies the switch's full box
   (opacity: 0, not display: none) so it stays clickable/focusable
   right where it visually is. */
.toggle-switch { position: relative; display: inline-block; width: 40px; height: 22px; vertical-align: middle; }
.toggle-switch input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
  z-index: 1;
}
.toggle-track {
  position: absolute;
  inset: 0;
  background: var(--border);
  border-radius: 999px;
  transition: background 0.15s;
}
.toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: 50%;
  transition: left 0.15s;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.toggle-switch input:checked ~ .toggle-track { background: var(--accent); }
.toggle-switch input:checked ~ .toggle-thumb { left: 20px; }
.toggle-field { display: flex; align-items: center; gap: 10px; }
.toggle-field-label { font-weight: 600; }

.fy-line { color: var(--muted); font-size: 0.9rem; margin: -6px 0 20px; }

/* Print/PDF-only report letterhead (Client name + city) -- see the
   .print-only rule below, and trial_balance.html for where this gets
   its text. Bold, one point larger than the grid header text (the
   size Sabari measured his request against), calc() mixing rem and pt
   directly so it always stays exactly --grid-header-size + 1pt even if
   that variable ever changes. */
.report-letterhead { font-weight: bold; font-size: calc(var(--grid-header-size) + 1pt); margin: 0 0 6px; color: var(--ink); }

/* Mirror image of .no-print (which has no rule out here because
   "visible on screen" is already the default) -- .print-only needs the
   opposite default, hidden on screen, and only .no-print's own
   @media print block flips it back on. */
.print-only { display: none; }

/* Shared by the persistent shell nav (.appnav-link.menu-disabled) and
   the Menu Builder's own "(no screen linked yet)" hint -- the old
   boxed-grid landing-page menu that first introduced this class is
   gone (the menu lives in the shell now, see base.html), but the
   class name stayed since both remaining users already relied on it. */
.menu-disabled { color: #b8c0cc; font-size: 0.95rem; }
.menu-disabled em { font-style: normal; font-size: 0.8em; }

/* The WHOLE tree -- every level, not just one sibling group -- is ONE
   6-column grid: label, then one column EACH for Move/+Add Child/
   +Separator/Edit/Delete, so every one of those aligns individually top
   to bottom (Sabari) instead of just "actions as a block" -- a row
   missing +Add Child/+Separator (a Separator itself, or a leaf at max
   depth) still renders an EMPTY cell in those two columns (see
   menu_builder.html) purely to hold its place in the column order, so
   Edit/Delete don't slide left into the gap. Column 1 is sized to the
   single widest label anywhere in the tree, and columns 2-6 line up on
   every row regardless of depth. <li>, .catalog-row AND a nested
   <ul class="catalog-tree"> (a heading's own children) are ALL
   collapsed with display: contents, so a heading's children flow as
   flat items straight into this SAME grid instead of starting a
   narrower/wider grid of their own one level down. Indentation moves
   from the old nested-ul's own padding-left onto each row's own label
   span instead (menu_builder.html's inline `padding-left`, scaled by
   node.depth) -- a display:contents element can't render padding/
   border/background of its own. Folding a heading still works exactly
   as before: its .catalog-children ul is what gets `hidden` (see the
   [hidden] override further below), which removes that whole flattened
   subtree from the grid in one shot, display: contents or not. */
.catalog-tree {
  display: grid;
  grid-template-columns: max-content max-content max-content max-content max-content max-content;
  align-items: center;
  column-gap: 10px;
  list-style: none;
  margin: 0;
  padding-left: 0;
}
.catalog-tree > li,
.catalog-row,
.catalog-tree > li > .catalog-tree {
  display: contents;
}
.catalog-row > span:first-child,
.catalog-row > .catalog-mover,
.catalog-row > .catalog-add-child,
.catalog-row > .catalog-add-sep,
.catalog-row > .catalog-build,
.catalog-row > .catalog-edit,
.catalog-row > .catalog-delete,
.catalog-row > .client-name,
.catalog-row > .client-address,
.catalog-row > .client-city,
.catalog-row > .client-menu,
.catalog-row > .client-status,
.catalog-row > .client-login {
  padding: 2px 0;
}
.catalog-row .mono { color: var(--muted); font-size: 0.85em; }
/* Grid items stretch to fill their column by default -- harmless for
   plain left-aligned content, but each action cell still gets an
   explicit justify-self so an EMPTY placeholder cell (see above) never
   accidentally centers/stretches its (nonexistent) content in a way
   that shifts the next column. Shared by both .catalog-tree (Menu
   Builder) and .tmpl-tree (Menu Templates list) below -- same idea,
   just a different column count per page. */
.catalog-mover, .catalog-add-child, .catalog-add-sep, .catalog-build, .catalog-edit, .catalog-delete {
  text-align: left;
  justify-self: start;
  white-space: nowrap;
}

/* Fold/expand -- same look as accheads.html's own .acc-toggle, kept as
   a separate class rather than reused directly since that one leans on
   its own .acc-group-row flex `gap` for spacing, which .catalog-row's
   grid-cell label span doesn't have; the margin-right here does the
   same job. .catalog-toggle-spacer is the same width on a LEAF row (no
   children, so no toggle button) purely so every row's label text
   still starts at the same x position regardless. Folding a heading
   just hides its own .catalog-children ul -- toggleNode()/setAllNodes()
   below are menu_builder.html's own copy of accheads.html's
   toggleGroup()/setAllGroups(). The [hidden] rule needs 3 class-level
   selectors (not just 2) to reliably outrank `.catalog-tree > li >
   .catalog-tree { display: contents }` above (2 classes + the `li`
   type selector = the same specificity tier `.catalog-children[hidden]`
   alone sits at, and ties go to whichever rule is LAST -- not worth
   relying on source order for this). */
.catalog-toggle {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--muted);
  font-size: 0.7rem;
  width: 16px;
  margin-right: 6px;
}
.catalog-toggle-spacer { display: inline-block; width: 16px; margin-right: 6px; }
.catalog-tree .catalog-children[hidden] { display: none; }

/* Separator row in the Menu Builder -- a thin rule taking up column 1
   (so it stretches to the tree's own single max label width, same as
   every other row's label), same action columns as every other row so
   Move/Edit/Delete still line up. More room AFTER the rule than before
   it, so the next item down doesn't crowd it -- top padding matches
   every other (now-tightened) row exactly, only the bottom is bigger. */
.catalog-separator-row > span:first-child,
.catalog-separator-row > .catalog-mover,
.catalog-separator-row > .catalog-add-child,
.catalog-separator-row > .catalog-add-sep,
.catalog-separator-row > .catalog-edit,
.catalog-separator-row > .catalog-delete {
  padding: 2px 0 7px;
}
.catalog-separator-line {
  width: 100%;
  border-top: 1px solid var(--border);
  position: relative;
  height: 0;
}
.catalog-separator-label {
  position: relative;
  top: -9px;
  background: var(--panel);
  padding-right: 8px;
  font-size: 0.78rem;
  color: var(--muted);
}

/* Menu Templates screen -- outer layer of its two-layer tree, one
   <details> per Client Type, holding a .tmpl-tree of that type's
   templates as the inner layer. Plain top-to-bottom stack, not the
   floating .appnav-dropdown panel -- this is page content, not a
   topbar menu. */
.type-group {
  border-bottom: 1px solid var(--border);
  padding: 10px 0;
}
.type-group:last-of-type { border-bottom: none; }
/* `<summary>`'s native disclosure triangle is its default `display:
   list-item` marker -- overriding display to flex (needed for the
   count badge to dock on the right via space-between) drops that
   marker with nothing standing in for it, which is why this looked
   like it had no expand/collapse affordance at all. list-style/
   ::-webkit-details-marker below explicitly suppress whatever the
   browser would still try to draw, and the ::before glyph on the
   FIRST child (not on .type-group-summary itself) replaces it without
   adding a 3rd flex item that would throw off the space-between
   above -- same &#9660;/&#9654; glyphs menu_builder.html's own
   toggleNode() uses, so both screens read as the same control. */
.type-group-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  font-weight: 600;
  padding: 2px 0;
  list-style: none;
}
.type-group-summary::-webkit-details-marker { display: none; }
.type-group-summary > span:first-child::before {
  content: "\25B6";
  display: inline-block;
  width: 14px;
  color: var(--muted);
  font-size: 0.7em;
}
.type-group[open] > .type-group-summary > span:first-child::before {
  content: "\25BC";
}
.type-group-count {
  color: var(--muted);
  font-weight: 400;
  font-size: 0.85em;
}
.type-group .tmpl-tree, .type-group .client-tree { margin-top: 8px; }
.empty-type { color: var(--muted); font-size: 0.85rem; margin: 8px 0 0; }

/* Menu Templates list -- same per-action-column alignment idea as the
   Menu Builder tree above (label, then one column per action, so
   Build Menu/Edit/Delete each line up top to bottom), just its own
   grid rather than reusing .catalog-tree: this list is flat (no
   nesting to flatten) and only has 3 actions, not 5, and each Client
   Type's own <ul> here is deliberately its OWN grid -- one type's
   longer template names shouldn't push another type's columns over. */
.tmpl-tree {
  display: grid;
  grid-template-columns: max-content max-content max-content max-content;
  align-items: center;
  column-gap: 10px;
  list-style: none;
  margin: 0;
  padding-left: 0;
}
.tmpl-tree > li { display: contents; }

/* Clients list -- same tree/grouping concept as the Menu Templates list
   right above (one collapsible <details class="type-group"> per Client
   Type, same disclosure marker, same per-column alignment idea), but with
   6 columns instead of 3 -- Name/Address/City/Menu Template/Status/Admin
   Login -- ahead of the shared Edit/Delete columns, so each lines up top
   to bottom within its own Client Type's group same as everywhere else in
   this file. Code isn't its own column at all: the type group heading
   already identifies the client's type, and Sabari wants the internal
   code folded into the Name cell instead, in parens, same idea as the
   "(40 items, 1 client)" meta the Menu Templates row hangs off its own
   name (see client_row() in clients.html). Own grid rather than reusing
   .tmpl-tree since the column count differs; each Client Type's <ul> is
   still its own grid instance for the same reason noted on .tmpl-tree
   above -- one type's longer client names shouldn't push another type's
   columns over. */
.client-tree {
  display: grid;
  grid-template-columns: max-content max-content max-content max-content max-content max-content max-content max-content;
  align-items: center;
  column-gap: 10px;
  list-style: none;
  margin: 0;
  padding-left: 0;
}
.client-tree > li { display: contents; }
.client-name, .client-address, .client-city, .client-menu, .client-status, .client-login {
  text-align: left;
  justify-self: start;
  white-space: nowrap;
}

/* Trial Balance/Profit & Loss A/c/Balance Sheet -- group/subgroup heading rows (recursive: a
   ledger_groups node at any depth), each head's own row indented one
   step further via an inline padding-left (depth isn't bounded, so no
   fixed set of CSS classes). Primary (top-level) group rows get a
   shaded background, same visual weight the real printed report gives
   them; a subgroup heading is bold but not shaded. */
/* Tighter vertical rhythm than the site's default .grid (9px top/bottom)
   -- this grid tends to run to a lot of rows (every ledger head, every
   FY), so a denser line-to-line spacing reads better here. */
.tb-grid th, .tb-grid td, .wide-grid th, .wide-grid td { padding-top: 5px; padding-bottom: 5px; }
.tb-group-row td { border-bottom: none; padding-top: 7px; }
.tb-primary-row td { background: var(--shade-strong); padding-top: 6px; padding-bottom: 6px; }
.tb-head-name { white-space: normal; }
.tb-grid th .mono, .wide-grid th .mono { display: block; font-size: 0.7rem; font-weight: 400; text-transform: none; color: var(--muted); }
/* Vertical rules between columns -- horizontal row borders (.grid's
   own border-bottom, plus totals-row/tb-primary-row's shading) are
   untouched; this only adds a right-hand divider to every cell except
   the last in its row. Every row in this table (group/subgroup heading
   rows included -- see trial_balance.html, which gives each one its
   own 5 real <td>s rather than a single colspan cell) has exactly 5
   cells, so the four divider lines run straight down the whole table
   without breaking across a group's heading bar. The one exception is
   the single "no ledger heads" empty-state row, which does span the
   full width -- nothing to divide there either way.
   .wide-grid (ACC_REP2 -- Profit & Loss A/c (Wide)/Balance Sheet
   (Wide)) shares this same divider rule so its 4 columns (Assets
   Description/Amount, Liabilities Description/Amount) get the same
   vertical rules -- deliberately its OWN class rather than reusing
   .tb-grid, since ACC_REP1's print rule below hides .tb-grid's 4th/5th
   columns and .wide-grid's 4th column (Liabilities Amount) is very
   much not a screen-only Group-Total column. */
.tb-grid th:not(:last-child), .tb-grid td:not(:last-child),
.wide-grid th:not(:last-child), .wide-grid td:not(:last-child) { border-right: 1px solid var(--border); }

/* Report toolbar (Export XL / PDF Portrait / PDF Landscape / Print) --
   same warm-orange pill-button look as pharma_platform's report
   screens, so a report screen here reads as the same family. */
.toolbar-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-toolbar {
  display: inline-block;
  background: #e8a765;
  color: #4a2e0a;
  border: none;
  padding: 8px 14px;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.btn-toolbar:hover { background: #dd9750; }

/* Printing / "Save as PDF" -- hide everything except the report
   itself. printReport() in trial_balance.html sets @page size just
   before calling window.print(); this just strips the chrome around
   the actual table. Also applies to the PDF Portrait/PDF Landscape
   toolbar buttons -- pdf_export.py's Playwright call explicitly
   emulates print media, so it renders under this same block, not a
   second copy of it. */
@media print {
  .topbar, .appnav, .app-footer, .no-print { display: none !important; }
  .content { padding: 0; }
  body { background: #fff; }

  /* .print-only's counterpart -- see the rule itself for why it
     defaults to hidden. The report letterhead (Client name + city) is
     the one thing using it right now. */
  .print-only { display: block; }

  /* Report heading ("Trial Balance") two points smaller once printed
     than its normal on-screen size (1.15rem) -- Sabari's own follow-up
     once the new letterhead line above it made the on-screen size look
     too heavy on paper. calc() keeps this relative to whatever
     .panel-head h1's own font-size actually is, rather than a second,
     easy-to-drift-out-of-sync magic number. */
  .panel-head h1 { font-size: calc(1.15rem - 2pt); }

  /* This second line -- "for the Period ... to ..." -- should match
     the grid header text's size once printed (it's 0.9rem normally,
     sized for on-screen prominence next to the smaller grid). */
  .fy-line { font-size: var(--grid-header-size); }

  /* .panel's own border/background/padding is one box wrapping the
     WHOLE report (title through the table's last row) -- a browser's
     default print pagination only draws that kind of box's border on
     its very first fragment's top edge and its very last fragment's
     bottom edge, leaving every page in between (and the first page's
     bottom, and the last page's top) with no border at all. Sabari
     flagged exactly that pattern on a real multi-page PDF.
     box-decoration-break: clone (Firefox/older WebKit still want the
     -webkit- prefix; Chromium, which is what pdf_export.py actually
     prints with, understands the unprefixed property) makes each
     printed page treat the box as its own complete copy instead --
     full border, background and padding on every single page. */
  .panel {
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
  }

  /* A <tfoot> carries the browser's built-in table-footer-group
     behaviour, which -- like a <thead> -- repeats it at the bottom of
     EVERY printed page, not just once at the table's real end (this is
     what put the Trial Balance's Total row on every page). Plain
     table-row-group semantics makes it behave like an ordinary row
     again: printed once, wherever the table itself actually ends.
     Affects every report's totals row the same way (Trial Balance,
     Day Book, the P&L/Balance Sheet statement tables), not just this
     one screen. */
  tfoot { display: table-row-group; }

  /* Trial Balance's 4th/5th columns (Credit/Debit <<Group-Total>>) are
     explicitly screen-only -- Sabari's own words when he first asked
     for them ("not linked to items in toolbar"), same reason Export XL
     never carried them. PDF Portrait/PDF Landscape print the live page
     itself (pdf_export.py), so without this they'd leak straight into
     the PDF the same way they would into a plain browser Print --
     hiding them here (rather than a second no-group-total template)
     covers Print and both PDF buttons at once, in the one place that
     already draws the line between "on screen" and "on paper". The
     vertical divider after column 3 (.tb-grid td:not(:last-child))
     keeps working unchanged: it's still not the DOM's last child, just
     a hidden one, so its right border still closes off the visible
     table instead of vanishing. */
  .tb-grid th:nth-child(4), .tb-grid th:nth-child(5),
  .tb-grid td:nth-child(4), .tb-grid td:nth-child(5) { display: none; }
}

.nested-tree { list-style: none; margin: 0; padding: 0; }
.nested-tree li { padding: 3px 0; }
.nested-tree .nested-tree {
  padding-left: 22px;
  margin-top: 2px;
  border-left: 1px solid var(--border);
}

.hint {
  color: var(--muted);
  font-size: 0.82rem;
  margin: -8px 0 12px;
}

.int-block + .int-block { margin-top: 28px; border-top: 1px solid var(--border); padding-top: 18px; }
.int-block-heading { font-size: 1rem; margin: 0 0 4px; }

/* Ledger (ledger.py) -- "Show Monthly Sub Totals" Month Total/Month
   Balance rows, same light shading idea as .grid .opening-row/
   .totals-row (see the .grid rule near the top of this file) but its
   own class since these sit INSIDE a block's grid alongside real
   entry rows, not just at the block's own head/foot. */
.grid .ledger-subtotal-row td { background: var(--shade); }

@media print {
  /* "Select New Page for Every Ledger" -- each block after the first
     starts its own printed page when ticked (int_rep.py passes the
     class only when that checkbox is on); a plain browser Print and
     both PDF Portrait/Landscape buttons all render under this same
     @media print block (see the block above), so one rule covers all
     three the same way it already does everywhere else in this file. */
  .int-block-pagebreak { page-break-before: always; }
}

/* Ledger Heads (accheads.py) -- collapsible chart-of-accounts tree.
   Genuinely nested <ul>/<li> (see accheads.html's own recursive
   macro), not the flat depth-indented .tb-grid table every printed
   report here otherwise uses -- that flat shape has no easy way to
   hide an arbitrary subtree, which this screen needs for its
   Expand/Collapse-All and search-filter behaviour. */
.acc-search {
  display: block;
  width: 100%;
  max-width: 420px;
  margin-bottom: 14px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.88rem;
}
.acc-tree, .acc-tree .acc-children { list-style: none; margin: 0; padding: 0; }
.acc-tree .acc-children { padding-left: 20px; }
.acc-tree .empty { color: var(--muted); padding: 10px 0; }

.acc-group-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 4px;
}
.acc-toggle {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--muted);
  font-size: 0.7rem;
  width: 16px;
  flex: none;
}
.acc-group-name { font-weight: 600; font-size: 0.9rem; }

.acc-head { padding: 3px 4px 3px 22px; }
.acc-head-link {
  color: var(--ink);
  text-decoration: none;
  font-size: 0.86rem;
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.acc-head-link:hover { color: var(--accent); text-decoration: underline; }
.acc-code { color: var(--muted); font-size: 0.76rem; font-variant-numeric: tabular-nums; }

/* Ledger Heads Add/Edit form (accheads_form.html) -- a .form-page
   with more field types than client_form.html needed (number,
   textarea), plus the party-detail block that's only enabled for
   Sundry Debtors/Sundry Creditors (see accheads_form.html's own
   script and reports_common.SUNDRY_PARTY_LEGACY_CODES). */
.form-page input[type="number"],
.form-page textarea {
  display: block;
  width: 100%;
  margin-top: 4px;
  padding: 7px 9px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.92rem;
  color: var(--ink);
  font-family: inherit;
}
.form-page textarea { resize: vertical; min-height: 52px; }

.acc-party-block {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 16px 8px;
  margin-top: 6px;
}
.acc-party-block[disabled] { opacity: 0.5; }
.acc-party-block legend { font-size: 0.9rem; font-weight: 600; padding: 0 6px; }

.acc-phone-row { display: flex; gap: 10px; }
.acc-phone-row input { flex: 1; }

/* Ledger picker tree (int_rep.py's interest_statement.html, and
   whichever picker screen reuses reports_common.compute_head_picker_tree()
   next) -- same .acc-tree/.acc-group/.acc-toggle shell as the Ledger
   Heads browse tree above, just scrolled inside a fixed-height box
   (same idea as the old .head-picker it replaced) and with a tick-box
   on every node instead of a plain link on heads only. */
.head-picker-tree {
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  min-width: 280px;
  max-width: 480px;
}

/* The picker's own popup (interest_statement.html's "Select Heads"
   button) -- same .overlay/.dialog shell users.html's Add/Edit User
   dialog already uses, just wider (a tree needs more room than a
   login form) and with its own small header/close-X since this
   dialog's h2 needs a close button next to it, unlike a plain form
   dialog that only ever closes via Save/Discard. */
.dialog-wide { width: 560px; }
.dialog-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.dialog-head h2 { margin: 0; }
.dialog-x {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  padding: 0 4px;
}
.dialog-x:hover { color: var(--ink); }
.acc-group-check, .acc-head-check {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 0.86rem;
}
.acc-head-check { justify-content: space-between; }
.acc-group-check input[type="checkbox"],
.acc-head-check input[type="checkbox"] { margin: 0; flex: none; }
.acc-head-check .rate { color: var(--muted); font-size: 0.76rem; font-variant-numeric: tabular-nums; }

/* Group the topbar's own right-hand links (Change Company/Display/
   Logout) under ONE margin-left:auto rather than the old bare
   ".topbar-row > .link" rule, which would otherwise also catch the
   new Display <details> (not a .link) and stop lining up with it. */
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.topbar-actions .link { margin: 0; font-size: 0.82em; padding: 0; }

/* Display dropdown (base.html's topbar, next to Change Company/
   Logout) -- reuses the exact same .appnav-dropdown/.appnav-panel
   shell the persistent Dynamic Menu's own dropdowns already use, so
   it looks like it belongs there rather than a one-off widget. */
.display-dropdown > summary { padding: 4px 6px; font-size: 0.85rem; }
/* This dropdown sits at the far right of the topbar (.topbar-actions
   is margin-left:auto) -- the generic .appnav-dropdown > .appnav-panel
   rule opens flush with the SUMMARY's left edge, which would run the
   panel straight off the right side of the viewport here. Anchoring
   to the right edge instead keeps it fully on-screen. */
.display-dropdown > .appnav-panel { left: auto; right: 0; }
.display-panel { min-width: 220px; padding: 12px; }
.display-section + .display-section { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.display-label { display: block; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); margin-bottom: 6px; }

.view-switch { display: flex; gap: 6px; }
.view-switch button {
  flex: 1;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--ink);
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 0.84rem;
  cursor: pointer;
}
.view-switch button.active { background: var(--accent); border-color: var(--accent); color: white; }

.theme-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.theme-swatch {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.18);
  cursor: pointer;
  padding: 0;
}
.theme-swatch.active { box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--accent); }

/* Hamburger toggle for the collapsed Mobile-view menu -- hidden in
   Normal view entirely (there's nothing to expand/collapse; the
   Dynamic Menu already renders inline, same as always). */
.nav-toggle {
  display: none;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--ink);
  border-radius: 6px;
  width: 34px;
  height: 34px;
  font-size: 1.1rem;
  cursor: pointer;
  flex: none;
}

/* Mobile view (session['view_mode'] == 'mobile', set via the Display
   dropdown's View switch -- see display.py) -- an explicit user
   choice, not a real-viewport media query, so it applies at any
   window size, same as pharma_platform's own view_mode design. Three
   things change: the Dynamic Menu collapses behind the hamburger
   above instead of sitting inline; grids get denser padding/text so
   more of a report fits without shrinking to illegible; and the
   side gutters tighten up since a phone has no room to spare. Wide
   report tables are wrapped in a horizontally-scrollable
   .mobile-scroll box by base.html's own script rather than by editing
   every report template individually -- every one of them already
   marks its table `class="grid ..."`, so one runtime query catches
   all of them. */
html[data-view="mobile"] .nav-toggle { display: inline-flex; align-items: center; justify-content: center; }
html[data-view="mobile"] .topbar-row { flex-wrap: wrap; row-gap: 8px; }
html[data-view="mobile"] .appnav {
  display: none;
  flex-direction: column;
  align-items: stretch;
  gap: 0;
}
html[data-view="mobile"] .appnav.nav-open { display: flex; }
html[data-view="mobile"] .appnav-link { padding: 10px 12px; }
html[data-view="mobile"] .appnav-dropdown > .appnav-panel { position: static; box-shadow: none; margin-top: 0; }
html[data-view="mobile"] .appnav-vrule { display: none; }

html[data-view="mobile"] .content { padding: 14px; }
html[data-view="mobile"] .panel { padding: 14px 14px; }
/* A report's title + its Export XL/PDF/Print toolbar (.panel-head)
   fight for the same row on a phone-width screen -- letting the title
   drop to its own line above the toolbar reads far better than
   squeezing both into one row until the title itself wraps mid-word. */
html[data-view="mobile"] .panel-head { flex-wrap: wrap; gap: 8px; }
html[data-view="mobile"] .grid th, html[data-view="mobile"] .grid td { padding: 6px 6px; font-size: 0.82rem; }
html[data-view="mobile"] .mobile-scroll { overflow-x: auto; }

/* Select Company window (select_firm.html) -- a standalone page (not
   base.html's shell -- there's no menu or nav-context yet at this
   point) styled as a floating window over a dark backdrop, the same
   shape as the old desktop app's own "Select Company" screen: a
   titled window holding the Company grid on top and the Financial
   Year grid underneath, rather than a plain full-page form. */
.selectwin-body {
  min-height: 100vh;
  margin: 0;
  background: radial-gradient(ellipse at top, #1e3a6e 0%, #0b1530 65%, #05070f 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 24px 16px 40px;
}
.selectwin-topbar {
  width: 100%;
  max-width: 760px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 4px 14px;
}
.selectwin-client {
  color: #cbd5e1;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.selectwin-logout {
  color: #93c5fd;
  font-size: 0.85rem;
  text-decoration: none;
}
.selectwin-logout:hover { text-decoration: underline; }

.selectwin {
  width: 100%;
  max-width: 760px;
  background: var(--panel);
  border-radius: 10px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  overflow: hidden;
}
.selectwin-titlebar {
  background: linear-gradient(180deg, #eef4fb 0%, #c9dcf2 100%);
  border-bottom: 1px solid #a9c2e0;
  padding: 12px 20px;
  font-weight: 700;
  font-size: 1.05rem;
  color: #1e3a6e;
}
.selectwin-body-inner { padding: 16px 22px 18px; }

/* Fixed-height scrollable grid box (the "browse window" look) --
   thead sticks to the top of its own scroll container rather than the
   header/body being two separately-laid-out tables, so column widths
   between header and rows can never drift apart the way that trick
   risks. */
.selectwin-scroll {
  max-height: 230px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
}
.selectwin-scroll-narrow { max-height: 170px; }
.selectwin-scroll .grid { margin: 0; }
/* The company grid box is a plain div made keyboard-focusable
   (tabindex, see select_firm.html's own script) so Up/Down can browse
   it -- a visible focus ring is the one bit of feedback that isn't
   already covered by the selected-row highlight below. */
.selectwin-scroll:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.selectwin-scroll .grid thead th {
  position: sticky;
  top: 0;
  background: #eef4fb;
  z-index: 1;
}
.selectwin-grid.narrow th:first-child, .selectwin-grid.narrow td:first-child { width: 34px; }
/* A stronger highlight than the plain .selected-row every other grid
   in the app uses -- this window's whole point is to show, at a
   glance, which company is currently in focus (same as the reference
   screenshot's solid highlight bar), so it needs to read clearly
   against a plain white grid rather than blend in. */
.selectwin-grid tr.selected-row { background: #dbeafe; }
.selectwin-grid tr.selected-row td { font-weight: 600; }

/* Tighter row rhythm than the site's default .grid (9px top/bottom,
   0.92rem/0.8rem text) -- this window's own grids, both scoped to
   .selectwin-grid so no other screen's tables are affected. One point
   smaller text, calc()'d off the same base sizes .grid itself uses
   rather than a second, easy-to-drift-out-of-sync magic number. */
.selectwin-grid th, .selectwin-grid td { padding: 5px 8px; font-size: calc(0.92rem - 1pt); }
.selectwin-grid th { font-size: calc(var(--grid-header-size) - 1pt); }

.selectwin-subhead {
  margin: 12px 0 6px;
  font-size: 0.82rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.selectwin-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}
