/* ==========================================================================
   Flip-Book — white-label skin for the self-hosted Bigcapital instance
   Injected by Nginx sub_filter at acct.reivelocity.com. See README.md.

   Nothing here is built into the container images, so `docker compose pull`
   cannot wipe it. The trade-off is that every selector below is aimed at
   upstream markup we do not control — so each one is anchored to something
   stable (a literal className, a BEM class, a Blueprint `bp4-*` class, or a
   link target), never to a styled-components hash. Anything positional is
   written so that a miss degrades to "unstyled", never to "broken".

   Load order note: PrivatePages' stylesheet is code-split and appended to
   <head> at runtime, i.e. AFTER this file. Overrides of anything it sets need
   !important — that is why it appears as often as it does below.
   ========================================================================== */

:root {
  /* Measured off the source artwork, not guessed. */
  --fb-deep:   #014755;   /* dominant ink: wordmark, house */
  --fb-mid:    #016b78;   /* secondary teal */
  --fb-light:  #0a8494;
  --fb-accent: #0fc2d6;   /* the arrow */

  --fb-ink:     #0f2b31;
  --fb-muted:   #5b7278;
  --fb-bg:      #f4f7f8;
  --fb-surface: #ffffff;
  --fb-border:  #dbe5e8;
  --fb-hairline:#eef4f5;

  /* Upstream's sidebar is #01115e navy in light mode. One variable rebrands
     the whole rail. Declared !important because PrivatePages.css lands later. */
  --color-sidebar-background: var(--fb-deep) !important;
}

/* ==========================================================================
   1. Logo substitution
   Every Bigcapital logo in the app is a Blueprint <Icon>, which renders
   <span class="bp4-icon bp4-icon-{name}"> around an inline SVG sized by
   width/height attributes. Painting our artwork into that span via ::after
   inherits the exact layout box upstream already reserved, so nothing shifts.
   ========================================================================== */

.bp4-icon-bigcapital,
.bp4-icon-mini-bigcapital {
  position: relative;
  display: inline-block;
}

.bp4-icon-bigcapital > svg,
.bp4-icon-mini-bigcapital > svg {
  opacity: 0 !important;
}

.bp4-icon-bigcapital::after,
.bp4-icon-mini-bigcapital::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("/flipbook/flipbook-horizontal.png") no-repeat center / contain;
}

/* The collapsed sidebar shows a square mini mark, so it gets the roundel
   rather than the horizontal lockup, which would letterbox to nothing. */
.bp4-icon-mini-bigcapital::after {
  background-image: url("/flipbook/flipbook-mark-white.png");
}

/* Dark-mode-only inline SVG. We force light, so this should never render —
   hidden defensively in case a future build reaches it another way. */
svg[data-icon="bigcapital-alt"] { opacity: 0 !important; }

/* On the dark sidebar the full-colour lockup would disappear. */
.sidebar .bp4-icon-bigcapital::after,
.sidebar__head-logo .bp4-icon-bigcapital::after {
  background-image: url("/flipbook/flipbook-horizontal-white.png");
}
.sidebar__head-logo svg { opacity: 0 !important; }

/* ==========================================================================
   2. Login  —  split-screen brand panel + form

   NOTE: `authentication` is a class on <body>, not on a wrapper div —
   Bigcapital applies it with a body-class helper. Confirmed against the
   rendered DOM, not inferred. The real tree is:

     body.authentication
       └ #root
           └ .App
               └ div                <- styled wrapper
                   └ div            <- fixed 384px column, padding-top:80px
                       ├ div        <- logo, text-align:center
                       └ div        <- TransitionGroup -> card + footer links

   The brand panel is a position:fixed pseudo-element rather than a grid
   track. <body> also carries #nprogress plus assorted script/link nodes, so
   a grid container here picks up stray grid items and sizes its tracks
   unpredictably; fixed positioning sidesteps all of that.
   ========================================================================== */

body.authentication {
  min-height: 100vh;
  background: var(--fb-surface);
}

body.authentication::before {
  content: "";
  position: fixed;
  inset: 0 auto 0 0;
  width: clamp(320px, 36%, 560px);
  background:
    url("/flipbook/flipbook-lockup-white.png") no-repeat center center / min(64%, 300px) auto,
    radial-gradient(circle at 28% 18%, rgba(15, 194, 214, 0.20), transparent 58%),
    linear-gradient(155deg, var(--fb-deep) 0%, #01596a 48%, var(--fb-mid) 100%);
}

body.authentication > #root {
  min-height: 100vh;
  margin-left: clamp(320px, 36%, 560px);
}

/* Centring lives on .App, not #root: upstream styles #root in ways that beat
   an unflagged rule here, and .App is the element that actually wraps the
   auth column. Flagged because both compete with app CSS loaded after us. */
body.authentication #root > .App {
  min-height: 100vh;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 40px 24px;

  /* .App carries a 1100px min-width for the dashboard's desktop layout. Left
     alone it overflows #root and the form centres against the wrong box (and
     the login page scrolls sideways on a phone). Irrelevant on an auth page. */
  width: 100% !important;
  min-width: 0 !important;
}

body.authentication #root > .App > div {
  width: 100%;
  display: flex;
  justify-content: center;
}

/* Drop the 384px column's 80px top padding so the card centres properly. */
body.authentication #root > .App > div > div {
  width: 400px !important;
  max-width: 100% !important;
  margin: 0 !important;
  padding-top: 0 !important;
}

/* The panel carries the logo, so hide the in-column one and the small
   "powered by" mark beneath the card. Scoped to the auth body, so the
   sidebar logo elsewhere in the app is unaffected. */
body.authentication .bp4-icon-bigcapital { display: none !important; }
body.authentication #root > .App > div > div > div:first-child {
  margin-bottom: 0 !important;
}

/* Card */
body.authentication div:has(> form) {
  background: var(--fb-surface) !important;
  border: 1px solid var(--fb-border) !important;
  border-radius: 14px !important;
  padding: 30px 28px !important;
  box-shadow: 0 12px 34px rgba(1, 71, 85, 0.09) !important;
}

/* Card heading.
   Every auth route (login, register, forgot, reset, invite) renders through
   this same card, so a hardcoded heading leaks — "Sign in" showed up on the
   forgot-password and register screens. Default to no heading and only add one
   where the form's own fields identify the page beyond doubt. Field names taken
   from the route chunks, not guessed:

     login    crediential + password + keepLoggedIn
     forgot   crediential, no password
     reset    password + confirm_password
     register email + first_name + last_name + password
     invite   first_name + last_name + password, no email

   Anything unrecognised simply renders headingless, which is the safe failure. */
body.authentication div:has(> form)::before {
  content: none;
  display: block;
  font-size: 21px;
  font-weight: 700;
  color: var(--fb-deep);
  letter-spacing: -0.01em;
  margin-bottom: 22px;
}

body.authentication div:has(> form):has(input[name="keepLoggedIn"])::before {
  content: "Sign in";
}
body.authentication div:has(> form):has(input[name="confirm_password"])::before {
  content: "Choose a new password";
}
body.authentication div:has(> form):has(input[name="email"])::before {
  content: "Create your account";
}
body.authentication div:has(> form):has(input[name="crediential"]):not(:has(input[name="password"]))::before {
  content: "Reset your password";
}
body.authentication div:has(> form):has(input[name="first_name"]):not(:has(input[name="email"]))::before {
  content: "Accept your invitation";
}

/* Fields */
body.authentication .bp4-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--fb-ink);
  margin-bottom: 6px;
}

body.authentication .bp4-input {
  height: 44px !important;
  border-radius: 9px !important;
  background: #fbfdfd !important;
  box-shadow: inset 0 0 0 1px var(--fb-border) !important;
  transition: box-shadow 0.15s ease;
}

body.authentication .bp4-input:focus {
  background: var(--fb-surface) !important;
  box-shadow: inset 0 0 0 1px var(--fb-mid),
              0 0 0 3px rgba(1, 107, 120, 0.16) !important;
}

body.authentication .bp4-control,
body.authentication .bp4-checkbox {
  color: var(--fb-ink);
  font-size: 13.5px;
}

/* Submit */
body.authentication .bp4-button.bp4-intent-primary {
  height: 46px;
  border-radius: 9px !important;
  font-weight: 600;
  letter-spacing: 0.01em;
  background: linear-gradient(180deg, var(--fb-mid), var(--fb-deep)) !important;
  box-shadow: none !important;
  transition: filter 0.15s ease;
}
body.authentication .bp4-button.bp4-intent-primary:hover { filter: brightness(1.08); }

body.authentication a {
  color: var(--fb-mid);
  font-weight: 600;
}
body.authentication a:hover { color: var(--fb-deep); }

/* Phone: drop the panel, put the full-colour stacked lockup above the form.
   Inputs stay >=16px so iOS does not zoom the viewport on focus. */
@media (max-width: 900px) {
  body.authentication::before { display: none; }
  body.authentication > #root { margin-left: 0; }
  body.authentication #root > .App { padding: 28px 18px; }
  body.authentication #root > .App > div > div > div:first-child {
    display: block !important;
    height: 116px;
    margin-bottom: 26px !important;
    background: url("/flipbook/flipbook-lockup.png") no-repeat center / contain;
  }
  body.authentication .bp4-input { font-size: 16px !important; }
}

/* ==========================================================================
   3. Homepage  —  card grid, curated to the flipper workflow

   Upstream renders .financial-reports > __section > (.section-title +
   __list > __item > a.title + p.desc).

   These are NOT unstyled: FinancialSheets-*.css (shared with the reports
   landing page) lays the items out as fixed 250x140 tiles in a wrapping flex
   row, and it is code-split so it loads AFTER this file. Everything that
   fights it therefore needs !important. The stylesheet the homepage chunk
   ships for itself, Homepage-*.css, styles .homepage__container — a class
   that is never rendered — so that one is genuinely dead and irrelevant.
   ========================================================================== */

.financial-reports {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 18px;
  max-width: 1120px;
  padding: 22px 28px 44px !important;
  align-items: start;
}

/* Branded banner spanning the grid. The tagline sits to the right of the
   lockup, which the background-position keeps clear. */
.financial-reports::before {
  content: "Accounting for Flippers";
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  min-height: 88px;
  padding-left: 208px;
  border-radius: 14px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.82);
  background:
    url("/flipbook/flipbook-horizontal-white.png") no-repeat 26px center / auto 40px,
    linear-gradient(120deg, var(--fb-deep) 0%, var(--fb-mid) 68%, var(--fb-light) 100%);
}

.financial-reports__section {
  background: var(--fb-surface);
  border: 1px solid var(--fb-border);
  border-radius: 12px;
  padding: 2px 20px 12px;
  box-shadow: 0 1px 2px rgba(1, 71, 85, 0.04);
}

.financial-reports .section-title {
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--fb-mid) !important;
  margin: 0 !important;
  padding: 16px 0 11px !important;
  border-bottom: 1px solid var(--fb-border);
}

/* Undo the fixed-tile flex row: a plain vertical list reads better in a card
   and keeps the page dense. */
.financial-reports__list {
  display: block !important;
  margin-left: 0 !important;
}

.financial-reports__item {
  width: auto !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 13px 0 !important;
  border: 0 !important;
  border-bottom: 1px solid var(--fb-hairline) !important;
}
.financial-reports__item:last-child { border-bottom: 0 !important; }

.financial-reports__item .title {
  display: block;
  font-size: 14.5px !important;
  font-weight: 600;
  color: var(--fb-deep);
  text-decoration: none;
}
.financial-reports__item .title:hover {
  color: var(--fb-mid);
  text-decoration: none;
}

.financial-reports__item .desc {
  margin: 3px 0 0 !important;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--fb-muted) !important;
}

/* Curation: a house flipper raises no sales invoices, estimates or quotes,
   and carries no inventory items — those two stock sections are noise.
   Matched on link target rather than :nth-child so upstream reordering the
   sections cannot silently hide the wrong one. */
.financial-reports__section:has(a[href="/invoices"]),   /* Accounts Receivable  */
.financial-reports__section:has(a[href="/items"]) {     /* Products & Inventory */
  display: none !important;
}

@media (max-width: 700px) {
  .financial-reports { padding: 14px 14px 32px !important; gap: 14px; }
  .financial-reports::before {
    min-height: 68px;
    padding-left: 0;
    justify-content: center;
    font-size: 0;
    background-size: auto 30px, cover;
    background-position: center, center;
  }
}

/* ==========================================================================
   4. Shell polish
   ========================================================================== */

body { background: var(--fb-bg); }

.dashboard__topbar-navbar { border-bottom: 1px solid var(--fb-border); }

/* Keep primary actions on-brand across the app, not just on login. */
.bp4-button.bp4-intent-primary {
  background-color: var(--fb-mid) !important;
  background-image: none !important;
}
.bp4-button.bp4-intent-primary:hover {
  background-color: var(--fb-deep) !important;
}

/* ==========================================================================
   5. The homepage dashboard  (rendered by /flipbook/flip-dash.js)

   Upstream's homepage is a feature directory. The cards below are the
   questions actually asked of these books: what is in the bank, what we owe,
   how the year is going, and what is tied up in houses.
   ========================================================================== */

/* The homepage's own container is `display: grid` with three fixed tile
   columns, so a plain insert makes the whole dashboard ONE 342px cell. Spanning
   every column restores full width and keeps it aligned with the tiles below,
   without hardcoding their width. `width: 100%` and `min-width: 0` cover the
   fallback anchor, which lands in a non-grid parent. */
#fb-dash {
  margin: 0 0 28px;
  grid-column: 1 / -1;
  width: 100%;
  min-width: 0;
}

.fb-dash-grid {
  display: grid;
  gap: 16px;
  /* TWO columns, not SF's three. REI's figures run to seven digits and its
     vendor names to thirty characters; at three tracks on a 1440px screen the
     amount wrapped under its own label on every inventory row. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* Cards size to their own content instead of stretching to the tallest in
     the row — without this, "Cash on hand" grew a 400px empty tail to match
     "What we owe" beside it. */
  align-items: start;
}
@media (max-width: 1000px) {
  .fb-dash-grid { grid-template-columns: 1fr; }
}

.fb-card {
  background: var(--fb-surface);
  border: 1px solid var(--fb-border);
  border-top: 3px solid var(--fb-mid);
  border-radius: 8px;
  padding: 16px 18px 12px;
  box-shadow: 0 1px 3px rgba(15, 43, 49, .06);
}

.fb-card-t {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--fb-deep);
  margin-bottom: 10px;
}

.fb-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 5px 0;
  font-size: 13.5px;
  color: var(--fb-ink);
}
.fb-row span { opacity: .78; }
/* Tabular figures so the decimal points line up down the column — the whole
   point of a money list. */
.fb-row b {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
.fb-row i { font-style: normal; opacity: .55; font-size: 12px; }

.fb-row.fb-total {
  border-top: 1px solid var(--fb-hairline);
  margin-top: 6px;
  padding-top: 9px;
}
.fb-row.fb-total span { opacity: 1; font-weight: 600; }
.fb-row.fb-total b { color: var(--fb-deep); }

/* A real account reading zero is dimmed, not hidden — the reader should see
   that it is zero, and wonder why. */
.fb-row.fb-zero span,
.fb-row.fb-zero b { opacity: .38; }

/* Negative where negative is impossible. Red because this is not a small
   number on these books: one account carries -$490,200.92 today. */
.fb-row.fb-bad b { color: #B3261E; }

.fb-subhead {
  margin-top: 14px;
  padding-top: 8px;
  border-top: 1px solid var(--fb-hairline);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--fb-muted);
}
.fb-row.fb-cards-total b { color: var(--fb-muted); }
.fb-row.fb-net { border-top-width: 2px; }

.fb-card-f {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--fb-hairline);
  font-size: 12px;
  color: var(--fb-muted);
}
.fb-card-f a { color: var(--fb-mid) !important; text-decoration: none; }
.fb-card-f a:hover { text-decoration: underline; }
.fb-card-f .fb-warn { color: #B3261E; }
/* A note that needs its own line rather than trailing a link with a dot. */
.fb-foot-note { margin-top: 6px; line-height: 1.45; }

.fb-none { font-size: 13px; opacity: .6; padding: 6px 0 2px; }
.fb-dash-loading { font-size: 13px; opacity: .5; padding: 8px 0 20px; }

/* An unreachable ledger must never render as zero. */
.fb-dash-err {
  background: #FDF3E7;
  border: 1px solid #E0A864;
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 13px;
  color: #6B4512;
}

/* The banners. Deliberately loud and full-width: a ledger that is behind, or a
   bank account reading minus half a million, rendering as "cash on hand" is the
   failure this whole dashboard could otherwise cause. */
.fb-banner {
  grid-column: 1 / -1;
  background: #FDF3E7;
  border: 1px solid #E0A864;
  border-left: 4px solid #E0A864;
  border-radius: 6px;
  padding: 10px 14px;
  margin-bottom: 4px;
  font-size: 13px;
  line-height: 1.5;
  color: #6B4512;
}
.fb-banner b { font-variant-numeric: tabular-nums; }
.fb-banner-bad {
  background: #FCEEED;
  border-color: #D99B95;
  border-left-color: #B3261E;
  color: #7A1F18;
}

/* -- "What we owe", grouped by vendor -------------------------------------
   573 open bills across 30-odd vendors. The vendor is a heading carrying its
   own subtotal, the bills beneath it carry only a number and a date, and the
   whole list scrolls inside the card so it cannot push the grid off-screen. */
.fb-vendors {
  max-height: 520px;
  overflow-y: auto;
  /* Room for the scrollbar so it never sits on top of the amounts. */
  padding-right: 6px;
}
.fb-row.fb-vendor {
  margin-top: 12px;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--fb-border);
}
.fb-vendors > .fb-row.fb-vendor:first-child { margin-top: 0; }
.fb-row.fb-vendor span { opacity: 1; font-weight: 600; }
.fb-row.fb-vendor b { color: var(--fb-ink); }

.fb-row.fb-bill {
  padding: 3px 0 3px 12px;
  font-size: 13px;
  text-decoration: none;
  color: inherit;
  border-radius: 4px;
}
.fb-row.fb-bill:hover { background: var(--fb-hairline); }
.fb-bill-no {
  font-variant-numeric: tabular-nums;
  opacity: .75;
  flex: 0 0 auto;
  max-width: 38%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fb-bill-when {
  font-variant-numeric: tabular-nums;
  opacity: .5;
  font-size: 12px;
  margin-left: auto;
  padding-right: 10px;
  white-space: nowrap;
}

/* Due today or earlier: the WHOLE row reads red, not just the date. The amount
   is the thing being scanned for, so colouring only the date left the urgent
   number looking exactly like the rest. */
.fb-row.fb-bill.fb-overdue .fb-bill-no,
.fb-row.fb-bill.fb-overdue b { color: #B3261E; opacity: 1; }
.fb-row.fb-bill.fb-overdue .fb-bill-when { color: #B3261E; opacity: .8; }

/* A vendor with anything due carries the mark on its subtotal too, so the card
   reads at a glance without scanning every line under every vendor. */
.fb-row.fb-vendor.fb-vendor-od b { color: #B3261E; }

/* No due date is a DATA problem, not a money problem — the bill cannot be aged,
   so it is amber and named in the footer rather than painted red as though we
   knew it were late. */
.fb-row.fb-bill.fb-nodate .fb-bill-when { color: #8A6D1F; opacity: .95; }

/* The per-vendor trim. Quiet, because it is navigation and not a number. */
.fb-row.fb-bill.fb-more span { opacity: .55; font-style: italic; }

/* Rows that go somewhere get a hover, so it is discoverable that they do. */
.fb-row.fb-linked { text-decoration: none; color: inherit; border-radius: 4px; }
.fb-row.fb-linked:hover { background: var(--fb-hairline); }
