/* Backoffice — page-specific styles. Self-contained (doesn't reference
   v2/'s partner-info.css or mfd-tools.css, since this app can be
   deployed at a different path/host) but uses the same tokens/base/
   components as the rest of the site for a consistent look. */

/* — page layout: slim top bar (brand/search/logout) + left sidebar
   accordion nav + main content. Sidebar sections render from
   getModuleRegistry() grouped by category, plus the hardcoded
   Administration / Subscriptions & Billing / Reports & System / Account
   sections — see inc/layout.php. One <details> per section gives
   click-to-toggle with no JS; the inline script in layout.php enforces
   "only one section open at a time" and remembers the last-opened
   section per browser via localStorage (bo_nav_open_section). — */
/* Deliberately wider than the site-wide --max-width (1180px, tuned for
   marketing-page reading width): this is a data-dense admin app with a
   240px sidebar eating into that budget, so tables/grids were being
   squeezed on large monitors. 1800px keeps generous margins up to
   ~1920px screens while still capping line length on ultrawide displays. */
.bo-layout { display: flex; align-items: flex-start; max-width: 1800px; margin: 0 auto; }

.bo-sidebar {
  flex: 0 0 240px;
  width: 240px;
  position: sticky;
  top: 0;
  align-self: flex-start;
  max-height: 100vh;
  overflow-y: auto;
  padding: 20px 12px 40px;
  border-right: 1px solid var(--color-divider);
  background: #fff;
  transition: width 0.18s ease, padding 0.18s ease, border-color 0.18s ease;
}
/* Desktop "closable" sidebar — collapses to zero width instead of the
   off-canvas overlay used below 900px. Content isn't unmounted (so
   toggling back open doesn't need a re-render), just clipped and hidden
   from assistive tech while collapsed. */
.bo-sidebar--collapsed {
  flex-basis: 0;
  width: 0;
  padding-left: 0;
  padding-right: 0;
  border-right-color: transparent;
  overflow: hidden;
}
.bo-sidebar--collapsed > * { opacity: 0; pointer-events: none; }
.bo-sidebar__link,
.bo-sidebar__group summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 4px;
  color: var(--color-text) !important;
  cursor: pointer;
  list-style: none;
  user-select: none;
  font-size: 14px;
}
.bo-sidebar__group summary::-webkit-details-marker { display: none; }
.bo-sidebar__link:hover,
.bo-sidebar__group summary:hover { background: var(--color-accent-100); text-decoration: none; }
.bo-sidebar__group[open] > summary { background: var(--color-accent-100); font-weight: 600; }

.bo-sidebar__icon {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--color-accent-100);
  color: var(--color-accent-700);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
}
.bo-sidebar__label { flex: 1; }

.bo-sidebar__group summary::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.15s ease;
  margin-right: 2px;
}
.bo-sidebar__group[open] summary::after { transform: rotate(-135deg); }

.bo-sidebar__menu { display: flex; flex-direction: column; padding: 2px 0 6px 32px; }
.bo-sidebar__menu a {
  color: var(--color-text) !important;
  font-size: 13.5px;
  padding: 7px 10px;
  border-radius: 4px;
}
.bo-sidebar__menu a:hover { background: var(--color-accent-100); color: var(--color-accent-700) !important; text-decoration: none; }

.bo-sidebar__backdrop { display: none; }

.bo-sidebar-toggle {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 32px;
  height: 32px;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
}
.bo-sidebar-toggle span { display: block; width: 100%; height: 2px; background: #fff; }

/* Mobile-only "back" button, next to the hamburger — the sidebar covers
   navigation on desktop, but on mobile it's off-canvas (a deliberate
   tap to open), so there was no quick way back to the previous screen
   without the browser's own chrome. Hidden on desktop since the always-
   visible sidebar already serves that purpose there. */
.bo-back-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: transparent;
  border: none;
  color: #fff;
  cursor: pointer;
  padding: 0;
  flex: 0 0 auto;
}
@media (max-width: 900px) {
  .bo-back-btn { display: flex; }
}

.bo-main { flex: 1 1 auto; min-width: 0; max-width: none; margin: 0; padding: 24px var(--pad-inline) 60px; }

/* Header bar and footer inner width standardized to match the body's
   content width (.bo-layout, 1800px) instead of the site-wide
   --max-width (1180px, tuned for the narrower marketing pages) — see
   components.css. Backoffice-only override; the marketing site is
   untouched since it never loads this stylesheet. */
.site-header__bar,
.site-footer__inner { max-width: 1800px; }

@media (max-width: 900px) {
  .bo-layout { display: block; }
  .bo-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 260px;
    max-height: none;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    z-index: 200;
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.2);
  }
  .bo-sidebar--open { transform: translateX(0); }
  .bo-sidebar__backdrop--visible {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: 150;
  }
  .bo-main { padding: 20px var(--pad-inline) 48px; }
}

/* — header nav search form — plain <form><input></form>, reset out of
   .site-nav's uppercase/letter-spacing/nav-link styling so it reads as
   a normal search box, not a nav link. — */
.bo-nav__search { margin: 0; display: inline-flex; }
.bo-nav__search input[type="search"] {
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--font-body);
  font-size: 13px;
  padding: 6px 10px;
  border: 1px solid #ffffff59;
  border-radius: 3px;
  background: #ffffff1a;
  color: #fff;
  width: 150px;
}
.bo-nav__search input[type="search"]::placeholder { color: #ffffffa6; }
.bo-nav__search input[type="search"]:focus {
  outline: none;
  background: #fff;
  color: var(--color-text);
}
.bo-nav__search { position: relative; }
.bo-nav__search__results {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: max(280px, 100%);
  max-height: 360px;
  overflow-y: auto;
  background: #fff;
  color: var(--color-text);
  border-radius: 4px;
  box-shadow: 0 8px 24px rgba(0,0,0,.25);
  z-index: 200;
}
.bo-nav__search__results.is-open { display: block; }
.bo-nav__search__group { padding: 6px 12px 2px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--color-muted, #667); }
.bo-nav__search__item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border: none;
  background: none;
  cursor: pointer;
  font-size: 13.5px;
  color: var(--color-text);
}
.bo-nav__search__item .bo-nav__search__snippet { display: block; font-size: 12px; color: var(--color-muted, #667); margin-top: 2px; }
.bo-nav__search__item:hover, .bo-nav__search__item.is-active { background: #eef2ff; }
.bo-nav__search__empty, .bo-nav__search__hint { padding: 10px 12px; font-size: 13px; color: var(--color-muted, #667); }

/* — login / setup pages — */
.bo-center-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; }
.bo-login-card { width: min(420px, 100%); padding: 32px; background: #fff; }
.bo-login-title { font-size: 24px; margin: 0 0 4px; }
.bo-login-sub { font-size: 14px; color: #1b2140b3; margin: 0 0 20px; }

.bo-form { display: flex; flex-direction: column; gap: 16px; }
.bo-form .field label { display: block; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: #1b214099; margin-bottom: 6px; font-weight: 600; }

/* Two-column layout for long forms (e.g. amc-edit.php's ~35 fields) —
   halves the scroll height versus one field per row. h3 section headers,
   full-width elements (textareas, file inputs), and the submit button
   span both columns via .field--full / direct-child selectors. */
.bo-form--2col { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; align-items: start; }
.bo-form--2col > h3 { grid-column: 1 / -1; margin: 8px 0 -4px; }
.bo-form--2col > h3:first-child { margin-top: 0; }
.bo-form--2col > .field--full,
.bo-form--2col > button { grid-column: 1 / -1; }
@media (max-width: 700px) {
  .bo-form--2col { grid-template-columns: 1fr; }
}

/* Calculators (calculators.php, npscalc.php) — form/result/installments
   on the left, chart on the right, instead of everything stacked in one
   long column. Targets the panes' existing direct children by type/class
   rather than requiring new wrapper markup around all ~22 calculators.
   Inline max-width attributes on individual elements predate this and
   are overridden here since they'd otherwise out-specificity the grid. */
.calc-pane {
  display: grid;
  grid-template-columns: minmax(280px, 420px) minmax(260px, 1fr);
  gap: 4px 32px;
  align-items: start;
}
/* .calc-pane[hidden] out-specificities the bare .calc-pane rule above
   (0,0,2,0 vs 0,0,1,0) so the [hidden] attribute actually hides the
   pane — without this, every calculator's `display: grid` beats the
   browser's UA-stylesheet `[hidden] { display: none }` on the tie, and
   all ~22 panes render stacked on top of each other regardless of
   which nav tab is clicked. */
.calc-pane[hidden] {
  display: none;
}
.calc-pane > h3 { grid-column: 1 / -1; margin-top: 0; }
.calc-pane > .bo-form { grid-column: 1; max-width: none !important; }
/* Calculators run 4-14 fields per pane, so the app-wide .input sizing
   (designed for shorter, less repetitive forms elsewhere) makes these
   feel oversized and pushes the chart column further down before it's
   visible. Scoped here only — every other form in the app (Settings,
   GST, user management, etc.) keeps the standard sizing. */
.calc-pane .bo-form { gap: 10px; }
.calc-pane .bo-form .field label { margin-bottom: 3px; }
.calc-pane .bo-form .input { padding: 6px 10px; font-size: 13.5px; }
.calc-pane > .calc-result { grid-column: 1; }
.calc-pane > details.calc-installments { grid-column: 1; }
.calc-pane > canvas {
  grid-column: 2;
  grid-row: 2 / span 3;
  max-width: 100% !important;
  width: 100% !important;
  align-self: start;
  position: sticky;
  top: 88px;
}
.calc-pane > .calc-actions { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .calc-pane { grid-template-columns: 1fr; }
  .calc-pane > canvas { grid-column: 1; grid-row: auto; position: static; }
}

/* Collapsible installment/amortization table — collapsed by default so
   a 20-30 row projection doesn't dominate the page; the chart already
   shows the trend at a glance. */
.calc-installments { margin-top: 12px; }
.calc-installments summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--color-accent-700);
  padding: 6px 0;
  list-style: none;
}
.calc-installments summary::-webkit-details-marker { display: none; }
.calc-installments summary::before { content: "▸ "; display: inline-block; transition: transform 0.15s ease; }
.calc-installments[open] summary::before { transform: rotate(90deg); }
.calc-installments .table-scroll { overflow-x: auto; margin-top: 8px; }

/* Native <dialog> (edit modals: user-subscriptions.php, social-accounts.php,
   feedback-management.php, etc.) — no browser UA stylesheet constrains a
   dialog's height, so a form with several fields (date pickers, several
   labeled inputs) easily exceeds the viewport with nothing to fix it:
   the box just overflows top/bottom uncontrolled, with no scrollbar and
   often no visible backdrop dimming either. Pin it to the viewport
   center explicitly and cap its height so it always scrolls internally
   instead. Each page's own inline max-width/width/padding/border still
   apply on top of this (more specific, same properties untouched here). */
dialog {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  border-radius: 4px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28);
}
dialog::backdrop {
  background: rgba(10, 14, 20, 0.6);
}

/* First-time step tour (assets/js/tour.js) — a floating card next to
   the highlighted element, not a native <dialog>, since it has to sit
   beside a specific target on the page rather than centered over it. */
.bo-tour__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 14, 20, 0.35);
  z-index: 300;
}
.bo-tour__card {
  position: absolute;
  z-index: 301;
  width: min(320px, calc(100vw - 24px));
  background: #fff;
  border-radius: 6px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
  padding: 16px;
  transition: top 0.2s ease, left 0.2s ease;
}
.bo-tour__step { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: #1b214099; font-weight: 700; margin-bottom: 4px; }
.bo-tour__title { margin: 0 0 6px; font-size: 15px; }
.bo-tour__text { margin: 0 0 14px; font-size: 13.5px; color: #1b2140cc; }
.bo-tour__actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.bo-tour__highlight {
  position: relative;
  z-index: 301;
  outline: 3px solid var(--color-accent, #2f6feb);
  outline-offset: 3px;
  border-radius: 4px;
  background: #fff;
}

/* Native <dialog> close button — an X in the corner instead of a
   full-width "Close dialog" text button competing with the real actions
   (Approve/Reject/etc.) at the bottom. */
.dialog-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border: 0;
  background: transparent;
  color: #1b214099;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
}
.dialog-close:hover { background: var(--color-accent-100); color: var(--color-text); }

/* pay.php plan picker — billing-cycle pills inside each plan card. */
.plan-picker-cycle { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
.plan-picker-cycle-opt {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 5px 10px; border: 1px solid var(--color-divider); border-radius: 999px;
  font-size: 12px; cursor: pointer; user-select: none;
}
.plan-picker-cycle-opt:has(input:checked) {
  background: var(--color-accent-100); border-color: var(--color-accent-700); color: var(--color-accent-700); font-weight: 600;
}
.plan-picker-cycle-opt input { margin: 0; }
.bo-checkbox-row { margin-bottom: 18px; }
.bo-checkbox-row label { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 500; cursor: pointer; }

.bo-flash { padding: 10px 14px; margin-bottom: 16px; font-size: 14px; border-left: 3px solid; }
.bo-flash--error { background: #fdeceb; border-color: var(--color-red); color: #7a2a22; }
.bo-flash--success { background: var(--color-accent-100); border-color: var(--color-green); color: #14532d; }
.bo-flash--warn { background: #fff8e6; border-color: #92600a; color: #92600a; }

/* — dashboard tiles (self-contained equivalents of partner-info's hub-* classes) — */
.hub-intro { max-width: 700px; }
.hub-intro p { font-size: 15px; line-height: 1.6; color: #1b2140cc; }
.hub-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.hub-card { padding: 20px; background: #fff; position: relative; }
.hub-meta, .bo-meta { font-size: 13px; color: #1b2140b3; margin: 4px 0; }
.hub-section-head { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }

/* — chips/links row (AMC "Visit site" links, badge rows) — */
.hub-links { display: flex; flex-wrap: wrap; gap: 8px; }
.hub-chip {
  font-size: 12.5px;
  font-family: var(--font-heading);
  letter-spacing: 0.03em;
  padding: 7px 12px;
  border: 1px solid #1b214029;
  color: var(--color-text);
  text-decoration: none;
}
.hub-chip:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* — two-column form/result layout (finplanner, adv-finplanner) — */
.mfd-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; align-items: start; }
.mfd-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
/* !important is required here: npscalc.php/finplanner.php/
   adv-finplanner.php/feedback.php each set grid-template-columns via an
   inline style="" (e.g. "1fr 1.5fr") for their desktop ratio — inline
   styles always outrank an external stylesheet rule regardless of media
   query, so without !important this rule silently never applied on
   mobile and those pages kept a squeezed 2-column layout below 900px. */
@media (max-width: 900px) { .mfd-grid { grid-template-columns: 1fr !important; } }

/* — workflow-at-a-glance sequence flow (mfd-gst.php) — plain flexbox
   chain of steps + arrows, not a diagramming library (see the comment
   at its call site for why). Wraps naturally on narrow screens instead
   of needing a separate mobile layout. — */
.mfd-flow { display: flex; flex-wrap: wrap; align-items: stretch; gap: 6px 4px; }
.mfd-flow__node {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-width: 96px; padding: 10px 12px; border: 1px solid #1b214029; border-radius: 8px;
  background: #fff; text-decoration: none; color: var(--color-text); text-align: center;
  transition: border-color .15s ease, transform .15s ease;
}
.mfd-flow__node:hover { border-color: var(--color-accent); transform: translateY(-1px); }
.mfd-flow__node--time { border-color: var(--color-accent-100, #eaeeff); background: var(--color-accent-100, #eaeeff); }
.mfd-flow__label { font-size: 12px; font-weight: 600; line-height: 1.3; }
.mfd-flow__time { font-size: 11px; color: var(--color-accent-700, #23306e); font-weight: 700; }
.mfd-flow__arrow { display: flex; align-items: center; font-size: 16px; color: #1b214066; padding: 0 2px; }
@media (max-width: 700px) { .mfd-flow__arrow { display: none; } .mfd-flow__node { flex: 1 1 45%; } }

.bo-tile { display: block; text-decoration: none; color: inherit; transition: border-color .15s ease; }
.bo-tile:hover { border-color: var(--color-accent); }
.bo-tile h3 { font-size: 17px; margin: 0 0 6px; color: var(--color-text); }
.bo-tile--locked { opacity: .72; }
.bo-tile--locked:hover { opacity: 1; border-color: #92600a; }
.bo-tile__premium { position: absolute; top: 14px; right: 14px; }
.bo-tile__upgrade { display: block; margin-top: 8px; font-size: 12px; font-weight: 600; color: #92600a; }

/* — trial / usage progress bar — */
.bo-progress { height: 6px; background: #1b21400f; overflow: hidden; }
.bo-progress__bar { height: 100%; background: var(--color-accent); }

/* — generic content card — */
.bo-card { padding: 24px; background: #fff; position: relative; }
.bo-card h2 { font-size: 19px; margin: 0 0 14px; }
.bo-card h3 { font-size: 15px; margin: 18px 0 10px; }

/* — tables — */
.bo-table { width: 100%; border-collapse: collapse; font-size: 14px; margin-top: 12px; }
.bo-table th { text-align: left; padding: 10px 12px; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: #1b214099; border-bottom: 1px solid #1b214029; }
.bo-table td { padding: 10px 12px; border-bottom: 1px solid #1b214015; vertical-align: top; }
.bo-mono { font-family: ui-monospace, monospace; font-size: 12px; color: #1b2140b3; max-width: 320px; overflow-wrap: anywhere; }

/* — badges — */
.bo-badge { display: inline-block; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; padding: 3px 9px; background: #1b21400f; color: var(--color-text); }
.bo-badge--admin { background: var(--color-accent-100); color: var(--color-accent-700); }
.bo-badge--employee { background: #fff4e0; color: #92600a; }
.bo-badge--distributor { background: #e6f0ff; color: #1d4ed8; }
.bo-badge--on { background: #e6f7ee; color: #14532d; }
.bo-badge--off { background: #1b21400f; color: #1b214099; }
.bo-badge--warn { background: #fdeceb; color: #7a2a22; }
.bo-badge--muted { background: #1b21400f; color: #1b214099; }
.bo-badge--archived { background: #ede9fe; color: #5b21b6; }

/* — category sub-nav (tabs within a module, e.g. IFA/ND) — */
.category-nav { display: flex; flex-wrap: wrap; gap: 8px; }
.category-nav a {
  font-size: 13px;
  font-family: var(--font-heading);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 7px 14px;
  border: 1px solid #1b214029;
  color: var(--color-text);
  text-decoration: none;
}
.category-nav a:hover { border-color: var(--color-accent); color: var(--color-accent); }
.category-nav a.is-current { background: var(--color-accent); color: #fff; border-color: var(--color-accent); }

/* — search / filter rows — */
.bo-search-row, .bo-filter-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0; }
.bo-search-row .input, .bo-filter-row .input { width: auto; flex: 1 1 160px; }

/* — pagination — */
.bo-pagination { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 20px; }
.bo-pagination a { padding: 6px 11px; border: 1px solid #1b214029; font-size: 13px; color: var(--color-text); text-decoration: none; }
.bo-pagination a.is-current { background: var(--color-accent); color: #fff; border-color: var(--color-accent); }

@media (max-width: 640px) {
  .hub-grid { grid-template-columns: 1fr; }
  .bo-table { display: block; overflow-x: auto; }
}

/* — data-tool controls (mf-us-canada, banks-epayeezz: search/filter/sort/paginate/export tables) — */
.bo-tool-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; }
.bo-tool-controls .group { display: flex; align-items: center; gap: 6px; }
.bo-tool-controls .group label { font-size: 12px; color: #1b214099; white-space: nowrap; }
.bo-tool-controls select, .bo-tool-controls input[type="search"] { padding: 7px 10px; border: 1px solid #1b214029; background: #fff; font-size: 13px; font-family: inherit; }
.bo-table th.sortable { cursor: pointer; user-select: none; }
.bo-table th.sortable .caret { opacity: .45; margin-left: 3px; }
.bo-table-wrap { overflow-x: auto; }

.pill { display: inline-block; font-size: 11px; letter-spacing: 0.03em; padding: 3px 10px; border: 1px solid #1b214029; color: #1b214099; cursor: pointer; }
.pill.yes, .pill.live { background: #e6f7ee; color: #14532d; border-color: #b9e6cc; }
.pill.no { background: #fdeceb; color: #7a2a22; border-color: #f4c9c4; }
.pill.active { outline: 2px solid var(--color-accent); outline-offset: 1px; }

.bo-tool-footer { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-top: 14px; }
.bo-pagebtn { padding: 6px 12px; border: 1px solid #1b214029; background: #fff; font-size: 13px; cursor: pointer; }
.bo-pagebtn:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* — narrow side panel + wide main (eKYC PAN checker) — */
.bo-side-layout { display: grid; grid-template-columns: 300px 1fr; gap: 20px; align-items: start; }
@media (max-width: 900px) { .bo-side-layout { grid-template-columns: 1fr; } }
.bo-side-layout .bo-card { position: sticky; top: 16px; }
@media (max-width: 900px) { .bo-side-layout .bo-card { position: static; } }
.bo-step-list { font-size: 13px; color: #1b2140b3; line-height: 1.6; padding-left: 18px; margin: 10px 0; }
.bo-btn-stack { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }

/* — radio group (MFD GST: template / input-mode pickers) — */
.bo-radio-group { display: flex; flex-wrap: wrap; gap: 14px; font-size: 14px; }
.bo-radio-group label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; font-weight: 400; }

/* — loading overlay (client-side PDF signing feedback) — */
.bo-loading-overlay { position: fixed; inset: 0; background: #16204acc; display: none; align-items: center; justify-content: center; flex-direction: column; gap: 14px; z-index: 200; color: #fff; }
.bo-loading-overlay.is-active { display: flex; }
.bo-loader { width: 40px; height: 40px; border: 3px solid #ffffff40; border-top-color: #fff; border-radius: 50%; animation: bo-spin 0.8s linear infinite; }
@keyframes bo-spin { to { transform: rotate(360deg); } }

/* — floating quick-links cluster (bottom-right, every backoffice page) — */
.bo-fab { position: fixed; right: 20px; bottom: 20px; z-index: 120; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.bo-fab__toggle {
  width: 48px; height: 48px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--color-navy, #10213f); color: #fff; font-size: 24px; line-height: 1;
  box-shadow: 0 4px 14px #00000040; transition: transform .15s ease;
}
.bo-fab__toggle:hover { transform: scale(1.06); }
.bo-fab--open .bo-fab__toggle { transform: rotate(45deg); }
.bo-fab__menu {
  display: none; flex-direction: column; gap: 4px; background: #fff; border-radius: 12px;
  padding: 8px; box-shadow: 0 6px 20px #00000030; min-width: 150px;
}
.bo-fab--open .bo-fab__menu { display: flex; }
.bo-fab__menu a { padding: 8px 12px; border-radius: 8px; font-size: 13.5px; color: #1b2140; text-decoration: none; }
.bo-fab__menu a:hover { background: #1b21400d; }

/* — header notification bell + dropdown (every page, replaces the old
   dashboard-only inline banner list) — */
.bo-notif { position: relative; }
.bo-notif__toggle {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid #ffffff59; background: #ffffff1a;
  color: #fff; cursor: pointer; transition: background .15s ease;
}
.bo-notif__toggle:hover { background: #ffffff33; }
.bo-notif__badge {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 3px;
  border-radius: 999px; background: var(--color-red, #a53f3f); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.bo-notif__menu {
  display: none; position: absolute; right: 0; top: calc(100% + 10px); z-index: 60;
  width: min(340px, 90vw); max-height: 420px; overflow-y: auto; background: #fff; color: #1b2140;
  border-radius: 12px; box-shadow: 0 10px 30px #00000030;
}
.bo-notif--open .bo-notif__menu { display: block; }
.bo-notif__header { padding: 12px 16px; font-size: 13px; font-weight: 700; border-bottom: 1px solid #1b214014; }
.bo-notif__list { display: flex; flex-direction: column; }
.bo-notif__item { display: flex; gap: 8px; align-items: flex-start; padding: 12px 16px; border-bottom: 1px solid #1b214014; }
.bo-notif__item:last-child { border-bottom: none; }
.bo-notif__item-body { flex: 1 1 auto; min-width: 0; font-size: 13px; }
.bo-notif__item-body strong { display: block; margin-bottom: 2px; }
.bo-notif__item-body p { margin: 0 0 4px; color: #1b2140cc; white-space: pre-wrap; overflow-wrap: anywhere; }
.bo-notif__time { font-size: 11px; color: #1b214099; }
.bo-notif__dismiss {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer; color: #1b214099;
  font-size: 16px; line-height: 1; padding: 2px 4px;
}
.bo-notif__dismiss:hover { color: var(--color-red, #a53f3f); }
.bo-notif__empty { padding: 20px 16px; margin: 0; font-size: 13px; color: #1b214099; text-align: center; }

/* — header "New" changelog icon + dropdown (mirrors .bo-notif above,
   but items persist — only the unseen badge clears on open) — */
.bo-newfeat { position: relative; }
.bo-newfeat__toggle {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid #ffffff59; background: #ffffff1a;
  color: #fff; cursor: pointer; transition: background .15s ease;
}
.bo-newfeat__toggle:hover { background: #ffffff33; }
.bo-newfeat__badge {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 3px;
  border-radius: 999px; background: var(--color-amber-dark, #b5791a); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.bo-newfeat__menu {
  display: none; position: absolute; right: 0; top: calc(100% + 10px); z-index: 60;
  width: min(360px, 90vw); max-height: 440px; overflow-y: auto; background: #fff; color: #1b2140;
  border-radius: 12px; box-shadow: 0 10px 30px #00000030;
}
.bo-newfeat--open .bo-newfeat__menu { display: block; }
.bo-newfeat__header { padding: 12px 16px; font-size: 13px; font-weight: 700; border-bottom: 1px solid #1b214014; }
.bo-newfeat__list { display: flex; flex-direction: column; }
.bo-newfeat__item { padding: 12px 16px; border-bottom: 1px solid #1b214014; font-size: 13px; }
.bo-newfeat__item:last-child { border-bottom: none; }
.bo-newfeat__item-head { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }
.bo-newfeat__item-head strong { flex: 1 1 auto; min-width: 0; }
.bo-newfeat__tag { font-size: 9px; padding: 1px 6px; }
.bo-newfeat__item p { margin: 0 0 6px; color: #1b2140cc; }
.bo-newfeat__item-foot { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.bo-newfeat__time { font-size: 11px; color: #1b214099; }
.bo-newfeat__empty { padding: 20px 16px; margin: 0; font-size: 13px; color: #1b214099; text-align: center; }

/* — header favorites star + dropdown (mirrors .bo-notif above) — */
.bo-fav { position: relative; }
.bo-fav__toggle {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%; border: 1px solid #ffffff59; background: #ffffff1a;
  color: #fff; cursor: pointer; transition: background .15s ease;
}
.bo-fav__toggle:hover { background: #ffffff33; }
.bo-fav__toggle.is-favorited { color: var(--color-amber, #e2a53a); }
.bo-fav__badge {
  position: absolute; top: -4px; right: -4px; min-width: 16px; height: 16px; padding: 0 3px;
  border-radius: 999px; background: var(--color-accent, #3b56e0); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
.bo-fav__menu {
  display: none; position: absolute; right: 0; top: calc(100% + 10px); z-index: 60;
  width: min(340px, 90vw); max-height: 460px; overflow-y: auto; background: #fff; color: #1b2140;
  border-radius: 12px; box-shadow: 0 10px 30px #00000030;
}
.bo-fav--open .bo-fav__menu { display: block; }
.bo-fav__header { padding: 12px 16px; font-size: 13px; font-weight: 700; border-bottom: 1px solid #1b214014; }
.bo-fav__current {
  width: 100%; display: flex; align-items: center; gap: 10px; padding: 12px 16px;
  border: none; border-bottom: 1px solid #1b214014; background: none; cursor: pointer;
  font-size: 13px; color: var(--color-accent, #3b56e0); text-align: left;
}
.bo-fav__current:hover { background: #1b21400a; }
.bo-fav__current svg { flex: 0 0 auto; color: var(--color-amber, #e2a53a); }
.bo-fav__picker { display: flex; gap: 8px; padding: 12px 16px; border-bottom: 1px solid #1b214014; }
.bo-fav__picker select { flex: 1 1 auto; min-width: 0; font-size: 13px; padding: 6px 8px; border-radius: 6px; border: 1px solid #1b214026; }
.bo-fav__list { display: flex; flex-direction: column; }
.bo-fav__item { display: flex; gap: 8px; align-items: center; padding: 10px 16px; border-bottom: 1px solid #1b214014; }
.bo-fav__item:last-child { border-bottom: none; }
.bo-fav__item a { flex: 1 1 auto; min-width: 0; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bo-fav__remove {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer; color: #1b214099;
  font-size: 16px; line-height: 1; padding: 2px 4px;
}
.bo-fav__remove:hover { color: var(--color-red, #a53f3f); }
.bo-fav__empty { padding: 20px 16px; margin: 0; font-size: 13px; color: #1b214099; text-align: center; }

/* Notifications/New-features/Favorites dropdowns on mobile: each menu
   is `position:absolute; right:0` relative to its own ~34px icon
   button, not the viewport. Below 640px, the header bar wraps
   (site-header__bar has flex-wrap:wrap) and these icons can land near
   the LEFT edge of the screen — "right:0" then anchors a 300px+-wide
   menu off the right edge of that icon, pushing most of it past the
   left edge of the viewport (negative x), effectively invisible/
   unreachable. Pin all three to the viewport instead of their icon. */
@media (max-width: 640px) {
  .bo-notif__menu,
  .bo-newfeat__menu,
  .bo-fav__menu {
    position: fixed;
    left: 12px;
    right: 12px;
    top: 64px;
    width: auto;
    max-height: calc(100vh - 88px);
  }
}

/* — real, interactive GST filing checklist (period-scoped) — */
.bo-checklist { list-style: none; padding: 0; margin: 12px 0; }
.bo-checklist li { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid #1b214015; font-size: 14px; }
.bo-checklist li:last-child { border-bottom: none; }
.bo-checklist input[type="checkbox"] { margin-top: 3px; width: 16px; height: 16px; flex-shrink: 0; cursor: pointer; }
.bo-checklist .step-label.is-done { text-decoration: line-through; color: #1b214080; }
.bo-checklist .step-meta { display: block; font-size: 12px; color: #1b214099; margin-top: 2px; }

.bo-signatory-preview { display: flex; align-items: center; gap: 12px; padding: 10px 12px; background: #f6f7fb; border: 1px solid #1b214020; font-size: 13px; margin-bottom: 12px; }
.bo-signatory-preview img { height: 36px; max-width: 100px; object-fit: contain; background: #fff; border: 1px solid #1b214020; padding: 2px; }

/* — Multisheet: workbook parse summary card — */
.ms-summary { display: none; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; margin-top: 12px; padding: 12px; background: #1b21400a; }
.ms-summary__item { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.ms-summary__label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: #1b214099; }

/* — Multisheet: editable spreadsheet grid on multisheet-view.php — */
.ms-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0; }
.ms-toolbar .group { display: flex; align-items: center; gap: 6px; }
.ms-toolbar select, .ms-toolbar input[type="search"] { padding: 7px 10px; border: 1px solid #1b214029; background: #fff; font-size: 13px; font-family: inherit; }
.ms-toolbar .spacer { flex: 1 1 auto; }
.ms-dirty-dot { display: none; width: 8px; height: 8px; border-radius: 50%; background: var(--color-red, #c0392b); margin-left: 6px; vertical-align: middle; }
.ms-dirty-dot.is-visible { display: inline-block; }

.ms-grid-wrap { overflow: auto; max-height: 70vh; border: 1px solid #1b214029; }
.ms-grid { width: 100%; border-collapse: collapse; font-size: 13px; }
.ms-grid th, .ms-grid td { border: 1px solid #1b214020; padding: 0; white-space: nowrap; }
.ms-grid thead th { background: #1b21400f; position: sticky; top: 0; z-index: 2; padding: 6px 8px; font-size: 11px; text-transform: none; text-align: left; }
.ms-grid thead th .ms-colhead { display: flex; align-items: center; gap: 4px; cursor: pointer; user-select: none; }
.ms-grid thead th .ms-colhead .caret { opacity: .5; font-size: 10px; }
.ms-grid thead th .ms-col-del { border: none; background: none; cursor: pointer; color: #1b214099; font-size: 13px; line-height: 1; padding: 2px 4px; }
.ms-grid thead th .ms-col-del:hover { color: var(--color-red, #c0392b); }
.ms-grid thead tr.ms-filter-row th { position: sticky; top: 27px; background: #fff; padding: 4px 6px; z-index: 1; }
.ms-grid thead tr.ms-filter-row input { width: 100%; box-sizing: border-box; padding: 4px 6px; border: 1px solid #1b214029; font-size: 12px; font-family: inherit; }
.ms-grid td { vertical-align: top; }
.ms-grid td .ms-cell { display: block; padding: 6px 8px; min-width: 60px; outline: none; white-space: pre-wrap; word-break: break-word; }
.ms-grid td .ms-cell:focus { background: var(--color-accent-100, #e8edff); }
.ms-grid td .ms-cell.is-invalid { outline: 2px solid var(--color-red, #c0392b); outline-offset: -2px; background: #fdeceb; }
.ms-grid td.ms-rownum-cell { background: #1b21400a; color: #1b214099; text-align: right; padding: 6px 8px; font-size: 12px; white-space: nowrap; }
.ms-grid td.ms-rowdel-cell { text-align: center; padding: 4px; }
.ms-grid td.ms-rowdel-cell button { border: none; background: none; cursor: pointer; color: #1b214099; font-size: 13px; }
.ms-grid td.ms-rowdel-cell button:hover { color: var(--color-red, #c0392b); }
.ms-grid tbody tr.is-hidden { display: none; }

.ms-statusbar { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; margin-top: 10px; padding: 8px 12px; background: #1b21400a; font-size: 12px; color: #1b214099; }
.ms-statusbar strong { color: var(--color-text); }

@media (max-width: 640px) {
  .ms-grid-wrap { max-height: 60vh; }
}

/* — Multisheet's own two-pane shell (upload + sheet list on the left,
   content on the right) — restyled from the original prototype's
   aside/section layout (pv1/modules/multisheet/multisheet.html), kept
   visually familiar but rebuilt on this app's real tokens/components
   and, unlike the prototype, backed by multisheet.php's actual
   database persistence rather than an in-memory JS object. — */
.ms-shell { display: flex; align-items: flex-start; gap: 20px; margin-top: 4px; }
.ms-aside {
  flex: 0 0 260px; width: 260px; background: var(--color-bg, #fff);
  border: 1px solid var(--color-divider); border-radius: 10px; padding: 16px;
}
.ms-aside h3 { margin: 0 0 12px; font-size: 16px; color: var(--color-accent-700); }
.ms-aside .bo-meta { margin: 0 0 6px; }

.ms-file-upload { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.ms-file-upload input[type="file"] { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); }
.ms-file-label {
  display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px;
  border-radius: 6px; font-weight: 600; font-size: 13px; cursor: pointer;
  background: var(--color-accent); color: #fff; transition: background .15s ease;
}
.ms-file-label:hover { background: var(--color-accent-600); }
.ms-file-name { font-size: 12.5px; color: var(--color-text); opacity: .7; word-break: break-all; }

.ms-aside-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }

.ms-sheet-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.ms-sheet-list__empty { font-size: 13px; color: var(--color-text); opacity: .6; margin: 4px 0; }
.ms-sheet-list__item {
  display: flex; align-items: center; gap: 6px; border-radius: 6px;
}
.ms-sheet-list__item:hover { background: var(--color-accent-100); }
.ms-sheet-list__link {
  flex: 1 1 auto; min-width: 0; padding: 8px 8px; font-size: 13.5px;
  color: var(--color-text) !important; text-decoration: none !important;
}
.ms-sheet-list__link:hover { color: var(--color-accent-700) !important; }
.ms-sheet-list__link .ms-sheet-list__count { display: block; font-size: 11.5px; opacity: .6; }
.ms-sheet-list__delete {
  flex: 0 0 auto; border: 0; background: none; cursor: pointer; color: #1b214099;
  font-size: 15px; line-height: 1; padding: 4px 8px;
}
.ms-sheet-list__delete:hover { color: var(--color-red); }

.ms-content { flex: 1 1 auto; min-width: 0; }

@media (max-width: 900px) {
  .ms-shell { display: block; }
  .ms-aside { width: auto; margin-bottom: 20px; }
}

/* — Common Report Framework: the shared branded print template
   (inc/report_template.php + assets/js/report-print.js). Hidden on
   screen; the ONLY thing visible when printReport() calls
   window.print(), regardless of which page/module triggered it. — */
.report-print-root { display: none; }
@media print {
  body > *:not(#reportPrintRoot) { display: none !important; }
  #reportPrintRoot.report-print-root {
    display: block !important;
    font-family: var(--font-body, Arial, sans-serif);
    color: #1b2140;
    padding: 0;
  }
  @page { margin: 16mm 14mm; }

  .report-print__header {
    display: flex; justify-content: space-between; align-items: flex-start;
    border-bottom: 2px solid #1b2140; padding-bottom: 12px; margin-bottom: 16px;
  }
  .report-print__brand { display: flex; align-items: center; gap: 10px; }
  .report-print__logo { height: 40px; width: auto; }
  .report-print__company { font-size: 17px; font-weight: 700; }
  .report-print__tagline { font-size: 11px; color: #1b2140b3; }
  .report-print__meta { text-align: right; }
  .report-print__title { font-size: 15px; font-weight: 700; }
  .report-print__generated, .report-print__prepared-for { font-size: 11px; color: #1b2140b3; }

  .report-print__section { margin-bottom: 16px; page-break-inside: avoid; }
  .report-print__section h3 {
    font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em;
    border-bottom: 1px solid #1b214029; padding-bottom: 4px; margin: 0 0 8px;
  }
  .report-print__section ul { margin: 0; padding-left: 18px; font-size: 13px; }
  .report-print__result { font-size: 18px; font-weight: 700; }
  .report-print__table { width: 100%; border-collapse: collapse; font-size: 11px; }
  .report-print__table th, .report-print__table td { border: 1px solid #1b214029; padding: 5px 8px; text-align: left; }
  .report-print__table th { background: #1b21400f; }
  .report-print__charts { display: flex; flex-direction: column; gap: 14px; }
  .report-print__chart-figure { margin: 0; page-break-inside: avoid; }
  .report-print__chart-figure figcaption { font-size: 11px; font-weight: 600; color: #1b2140b3; margin-bottom: 4px; }
  .report-print__chart-figure img { max-width: 100%; border: 1px solid #1b214029; }

  .report-print__disclaimer {
    font-size: 10px; color: #1b2140b3; border-top: 1px solid #1b214029;
    padding-top: 8px; margin-bottom: 12px; font-style: italic;
  }
  .report-print__regulatory {
    font-size: 10px; color: #1b2140b3; margin-bottom: 12px;
  }
  .report-print__footer {
    font-size: 10px; color: #1b2140b3; border-top: 2px solid #1b2140;
    padding-top: 8px; display: flex; justify-content: space-between; gap: 16px;
  }
  .report-print__footer-legal { white-space: nowrap; }
}
