body {
  font-family: var(--eb-font-sans);
  background: hsl(var(--eb-neutral-100));
}

/* --- Floating daily-hours tracker, upper right on every page ---
   Fixed (not sticky/relative like the timer widget) since it's meant to
   stay visible while scrolling, independent of the topbar. z-index sits
   below Bootstrap's modal/backdrop range (1040+) so it never floats over
   a dialog, but above ordinary page content. Positioned below the topbar
   (its own height + a small gap) rather than overlapping it. */
.eb-daily-hours-tracker {
  position: fixed;
  /* Lower right, not upper right -- upper right collided with real
     page-level action buttons (Time Entries, Invoices, etc. all put their
     own "+ New" button in that same corner of the content area). */
  bottom: 1rem;
  right: 1rem;
  z-index: 15;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: hsl(var(--eb-brand-50));
  border: 1px solid hsl(var(--eb-brand-500) / 0.3);
  color: hsl(var(--eb-brand-700));
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.9rem;
  font-weight: 600;
  box-shadow: 0 2px 6px rgba(16, 24, 32, 0.08);
}

/* --- Quick-add timer widget, in the top bar on every page --- */

.eb-timer-widget {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: hsl(var(--eb-danger-100));
  border: 1px solid hsl(var(--eb-danger-500) / 0.3);
  border-radius: 999px;
  padding: 0.2rem 0.7rem;
}

/* Anchored under the pill rather than inline, so it never adds width to
   the topbar's flex row -- an inline error span was shifting the whole
   right-aligned nav group, and the shift changed depending on how many
   timers/other items were sharing that row. */
.eb-timer-error {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 0.3rem;
  white-space: nowrap;
  background: hsl(var(--eb-neutral-50));
  border: 1px solid hsl(var(--eb-danger-500) / 0.4);
  border-radius: 0.4rem;
  padding: 0.15rem 0.55rem;
  z-index: 20;
}

.eb-timer-clock {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: hsl(var(--eb-danger-500));
  min-width: 4.5em;
}

.eb-timer-widget-paused {
  background: hsl(var(--eb-neutral-200));
  border-color: hsl(var(--eb-neutral-500) / 0.5);
}

.eb-timer-widget-paused .eb-timer-clock {
  color: hsl(var(--eb-neutral-700));
}

.eb-timer-select {
  width: auto;
  max-width: 160px;
}

.eb-timer-activity {
  width: 120px;
}

/* Pause and Resume swap in and out of the same slot (see
   _timer_widget.html) as the PDF editor's auto-pause-on-inactivity flips
   the timer's state -- "Pause"/"Resume" are different lengths, and
   without a shared min-width the topbar's own rendered width changed on
   every flip. Confirmed real: the topbar is flex-wrap, so that width
   change could reflow it, visibly shifting every page's content below it
   -- happening on its own 15s poll interval regardless of what page was
   open or whether the user was doing anything at all. Sized for
   "Resume" + its icon, the longer of the two. */
.eb-timer-toggle-btn {
  min-width: 92px;
}

/* --- Paid stamp on the invoice detail page --- */

.eb-invoice-page-wrap {
  position: relative;
}

.eb-paid-stamp {
  position: absolute;
  top: 0;
  left: -18px;
  transform: rotate(-22deg);
  font-size: 2.5rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  color: hsl(var(--eb-success-500) / 0.55);
  border: 5px solid hsl(var(--eb-success-500) / 0.55);
  border-radius: 10px;
  padding: 0.1rem 1.1rem;
  pointer-events: none;
  z-index: 5;
}

a {
  color: hsl(var(--eb-info-500));
}

/* --- Shell: top navbar + left sidebar, mirrors MyCase's layout --- */

.eb-topbar {
  background: #fff;
  border-bottom: 1px solid hsl(var(--eb-neutral-300));
  box-shadow: 0 1px 2px rgba(16, 24, 32, 0.04);
  display: flex;
  align-items: center;
  /* flex-wrap so a wide right-side cluster (the timer widget while a timer
     is running, mainly) drops to its own line below ~768px instead of
     overflowing off-screen -- no min-height/vertical padding here since
     the bar should hug its tallest child (the banner logo) exactly, not
     add extra whitespace around it. */
  flex-wrap: wrap;
  padding: 0 1.25rem;
  position: sticky;
  top: 0;
  z-index: 20;
}

.eb-topbar .eb-brand {
  font-weight: 700;
  color: hsl(var(--eb-neutral-900));
  font-size: 1.05rem;
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.eb-brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
}

.eb-brand-mark img {
  width: 40px;
  height: 40px;
}

.eb-shell {
  display: flex;
  min-height: calc(100vh - 56px);
}

/* Below 768px, .eb-sidebar is also Bootstrap's .offcanvas.offcanvas-md (see
   base.html) -- a full-height slide-in drawer with its own backdrop, using
   Bootstrap's own positioning entirely. These desktop-only rules would
   otherwise fight that: they only apply at/above the same breakpoint where
   Bootstrap's offcanvas-md resets back to a normal static, always-visible
   element. */
@media (min-width: 768px) {
  .eb-sidebar {
    width: 224px;
    flex-shrink: 0;
    background: #fff;
    border-right: 1px solid hsl(var(--eb-neutral-300));
    padding: 1.25rem 0;
    /* Stays put as the main pane scrolls -- sticky to the viewport (below
       the topbar), with its own scrollbar in the unlikely case the nav
       itself is ever taller than the viewport. */
    position: sticky;
    top: 56px;
    height: calc(100vh - 56px);
    overflow-y: auto;
  }
}

.eb-sidebar .nav-link {
  color: hsl(var(--eb-neutral-700));
  padding: 0.55rem 1.25rem;
  border-radius: 0;
  font-size: 0.9rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  border-right: 3px solid transparent;
}

.eb-sidebar .nav-link i {
  color: hsl(var(--eb-neutral-500));
  font-size: 0.85rem;
  width: 1rem;
  text-align: center;
}

.eb-sidebar .nav-link.active {
  background: hsl(var(--eb-brand-50));
  color: hsl(var(--eb-brand-600));
  font-weight: 600;
  border-right-color: hsl(var(--eb-brand-500));
}

.eb-sidebar .nav-link.active i {
  color: hsl(var(--eb-brand-600));
}

.eb-sidebar .nav-link:hover {
  background: hsl(var(--eb-neutral-100));
}

.eb-sidebar-divider {
  height: 1px;
  background: hsl(var(--eb-neutral-200));
  margin: 0.75rem 1.25rem;
}

.eb-main {
  flex: 1;
  padding: 1.75rem 2rem;
  /* No max-width: tables (and everything else) scale with the actual
     browser window width, matching MyCase's own layout, instead of being
     capped at a fixed content width with empty space beside it on wide
     screens. min-width: 0 lets this flex child actually shrink below its
     content's intrinsic width when needed -- without it, a wide table
     could force the whole page to overflow horizontally instead of
     scrolling inside its own .eb-table-card. */
  min-width: 0;
}

.eb-main h1 {
  color: hsl(var(--eb-neutral-900));
  font-weight: 700;
}

/* --- Buttons --- */

.btn-cta-primary,
.btn-primary {
  background-color: hsl(var(--eb-brand-500));
  border-color: hsl(var(--eb-brand-500));
  color: #fff;
}

.btn-cta-primary:hover,
.btn-primary:hover,
.btn-cta-primary:focus,
.btn-primary:focus {
  background-color: hsl(var(--eb-brand-600));
  border-color: hsl(var(--eb-brand-600));
  color: #fff;
}

.btn-outline-secondary {
  color: hsl(var(--eb-neutral-700));
  border-color: hsl(var(--eb-neutral-300));
}

.btn-outline-secondary:hover {
  background: hsl(var(--eb-neutral-100));
  color: hsl(var(--eb-neutral-900));
  border-color: hsl(var(--eb-neutral-300));
}

/* --- Cards / panels (tables, forms, stat tiles all sit in these) --- */

.eb-card,
.card {
  background: #fff;
  border: 1px solid hsl(var(--eb-neutral-300));
  border-radius: 0.6rem;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.06);
}

.eb-table-card {
  background: #fff;
  border: 1px solid hsl(var(--eb-neutral-300));
  border-radius: 0.6rem;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.06);
  margin-bottom: 1.5rem;
  /* The card itself becomes the scrolling region for its table, so the
     column headers and search boxes (sticky, below) can stay in view
     while only the row data scrolls underneath them -- and so the page
     title above the card never has to scroll away either. */
  max-height: calc(100vh - 260px);
  overflow: auto;
}

.eb-table-card .table {
  margin-bottom: 0;
}

/* --- Sortable table headers, matches MyCase's /bills list --- */

.eb-table {
  background: #fff;
}

.eb-table thead {
  /* Both header rows (column labels + the wildcard-search inputs) live in
     one <thead>, so sticking the whole element keeps them stacked
     together without needing to hand-compute two separate offsets. */
  position: sticky;
  top: 0;
  z-index: 3;
}

.eb-table thead th {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: hsl(var(--eb-neutral-700));
  background: hsl(var(--eb-neutral-50));
  border-bottom: 1px solid hsl(var(--eb-neutral-300));
  white-space: nowrap;
  padding: 0.7rem 1rem;
}

.eb-table tbody td {
  vertical-align: middle;
  padding: 0.5rem 0.85rem;
  font-size: 0.8rem;
  border-bottom: 1px solid hsl(var(--eb-neutral-200));
}

.eb-table tbody tr:last-child td {
  border-bottom: none;
}

.eb-table tbody tr:hover {
  background: hsl(var(--eb-neutral-50));
}

.eb-table a {
  color: hsl(var(--eb-neutral-900));
  font-weight: 600;
  text-decoration: none;
}

.eb-table a:hover {
  color: hsl(var(--eb-brand-600));
}

/* --- Invoice status badges --- */

.eb-badge-draft { background: hsl(var(--eb-neutral-200)); color: hsl(var(--eb-neutral-800)); }
.eb-badge-sent { background: hsl(var(--eb-info-100)); color: hsl(var(--eb-info-500)); }
.eb-badge-partial { background: hsl(var(--eb-warning-100)); color: hsl(45 69% 30%); }
.eb-badge-paid { background: hsl(var(--eb-success-100)); color: hsl(var(--eb-success-500)); }
.eb-badge-overdue { background: hsl(var(--eb-danger-100)); color: hsl(var(--eb-danger-500)); }
.eb-badge-void { background: hsl(var(--eb-neutral-200)); color: hsl(var(--eb-neutral-700)); }
.eb-badge-beta { background: hsl(270 60% 92%); color: hsl(270 50% 40%); text-transform: uppercase; }
.eb-sidebar .nav-link .eb-badge-beta,
.dropdown-item .eb-badge-beta,
.list-group-item .eb-badge-beta {
  font-size: 0.55rem;
  padding: 0.1rem 0.4rem;
  margin-left: 0.2rem;
  vertical-align: 1px;
}

.eb-badge {
  display: inline-block;
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* --- Task expiration urgency (Task.urgency: none/ok/warning/critical) --- */

.eb-badge-ok { background: hsl(var(--eb-success-100)); color: hsl(var(--eb-success-500)); }
.eb-badge-warning { background: hsl(var(--eb-warning-100)); color: hsl(45 69% 30%); }
.eb-badge-critical { background: hsl(var(--eb-danger-100)); color: hsl(var(--eb-danger-500)); }

.eb-row-urgency-warning { background: hsl(var(--eb-warning-100) / 0.35); }
.eb-row-urgency-critical { background: hsl(var(--eb-danger-100) / 0.35); }

/* --- Calendar tab chips --- */

.eb-cal-chip {
  display: block;
  position: relative;
  font-size: 0.72rem;
  padding: 0.1rem 0.35rem;
  border-radius: 0.3rem;
  margin-bottom: 2px;
  text-decoration: none;
  /* overflow/ellipsis truncation lives on .eb-cal-chip-label (below), NOT
     here -- overflow:hidden on this element would also clip its own ::after
     tooltip, since that's a descendant positioned to render outside this
     box (top:100%). That's what silently broke the tooltip: the CSS was
     correct, but the hidden overflow on the same element cut it off before
     it could ever be seen. */
}
.eb-cal-chip-label {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* A CSS-only tooltip showing the chip's full (untruncated) label, instead
   of the native title="" tooltip -- browsers impose their own fixed ~0.5-1s
   hover delay on title tooltips with no way to shorten it, whereas a plain
   :hover pseudo-element appears the instant the CSS matches, no transition
   involved. aria-label (see calendar.html) keeps this accessible without
   also triggering a second, native tooltip alongside this one, since only
   title="" (not aria-label) does that. */
/* [aria-label] scoping matters here -- the color-key legend at the bottom
   of the Calendar page reuses .eb-cal-chip on plain, label-less <span>s just
   for the swatch styling; without this they'd still generate an empty (but
   padded/backgrounded) tooltip box on hover. */
.eb-cal-chip[aria-label]::after {
  content: attr(aria-label);
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 30;
  margin-top: 2px;
  background: hsl(var(--eb-neutral-900));
  color: #fff;
  padding: 0.3rem 0.5rem;
  border-radius: 0.3rem;
  font-size: 0.72rem;
  font-weight: 400;
  white-space: normal;
  width: max-content;
  max-width: 260px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  pointer-events: none;
}
.eb-cal-chip[aria-label]:hover::after,
.eb-cal-chip[aria-label]:focus-visible::after {
  display: block;
}
.eb-cal-chip-due { background: hsl(var(--eb-info-100)); color: hsl(var(--eb-info-500)); }
.eb-cal-chip-expire { background: hsl(var(--eb-neutral-200)); color: hsl(var(--eb-neutral-800)); }
.eb-cal-chip-disclosure { background: hsl(var(--eb-brand-50)); color: hsl(var(--eb-brand-600)); }
.eb-cal-chip-trial { background: hsl(var(--eb-danger-100)); color: hsl(var(--eb-danger-500)); }
.eb-cal-chip-urgency-warning { background: hsl(var(--eb-warning-100)); color: hsl(45 69% 30%); }
.eb-cal-chip-urgency-critical { background: hsl(var(--eb-danger-100)); color: hsl(var(--eb-danger-500)); }

.eb-calendar {
  background: #fff;
  border: 1px solid hsl(var(--eb-neutral-300));
  border-radius: 0.6rem;
  overflow: hidden;
}
.eb-calendar-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}
.eb-calendar-header {
  background: hsl(var(--eb-neutral-50));
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  color: hsl(var(--eb-neutral-700));
}
.eb-calendar-header > div {
  padding: 0.5rem;
  border-bottom: 1px solid hsl(var(--eb-neutral-300));
}
.eb-calendar-cell {
  min-height: 100px;
  /* Grid items default to min-width:auto, not 0 -- without this, a single
     long chip's intrinsic content width can inflate its whole column wider
     than its 1fr share, unevenly squeezing the other 6 columns in that row
     depending on how much text that day happens to have. This is what
     actually made the grid look uneven, more than the chip text itself --
     .eb-cal-chip's own overflow:hidden/ellipsis (below) can't kick in until
     the column is correctly held to 1fr in the first place. */
  min-width: 0;
  padding: 0.4rem;
  border-right: 1px solid hsl(var(--eb-neutral-200));
  border-bottom: 1px solid hsl(var(--eb-neutral-200));
}
.eb-calendar-cell-outside {
  background: hsl(var(--eb-neutral-50));
  color: hsl(var(--eb-neutral-500));
}
.eb-calendar-cell-today {
  /* inset box-shadow, not a border -- these cells already carry real
     border-right/border-bottom rules for the grid lines; a border here
     would add to the box model and throw off alignment with neighboring
     cells, where an inset shadow paints inside the existing box instead. */
  background: hsl(var(--eb-brand-50));
  box-shadow: inset 0 0 0 2px hsl(var(--eb-brand-500));
}
.eb-calendar-cell-today .eb-calendar-daynum {
  color: hsl(var(--eb-brand-600));
}
.eb-calendar-daynum {
  font-size: 0.8rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

/* Below 768px, seven cramped ~50px columns aren't usable -- switch to a
   single-column stacked agenda instead (each day its own full-width row,
   with the weekday now spelled out in .eb-calendar-daynum since column
   position no longer conveys it -- see calendar.html). Days outside the
   current month are dropped entirely rather than shown as empty padding
   rows, which only made sense as grid filler. */
@media (max-width: 767.98px) {
  .eb-calendar-header {
    display: none;
  }
  .eb-calendar-row {
    grid-template-columns: 1fr;
  }
  .eb-calendar-cell {
    min-height: 0;
  }
  .eb-calendar-cell-outside {
    display: none;
  }
}

/* --- Dashboard stat cards --- */

.eb-stat-card {
  background: #fff;
  border: 1px solid hsl(var(--eb-neutral-300));
  border-radius: 0.6rem;
  box-shadow: 0 1px 3px rgba(16, 24, 32, 0.06);
  padding: 1.1rem 1.35rem;
}

.eb-stat-card .eb-stat-value {
  font-size: 1.6rem;
  font-weight: 700;
  color: hsl(var(--eb-neutral-900));
}

.eb-stat-card .eb-stat-label {
  font-size: 0.72rem;
  color: hsl(var(--eb-neutral-700));
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
}

/* --- Forms --- */

.form-control:focus,
.form-select:focus {
  border-color: hsl(var(--eb-brand-500));
  box-shadow: 0 0 0 0.2rem hsl(var(--eb-brand-100));
}

label {
  font-weight: 600;
  font-size: 0.85rem;
  color: hsl(var(--eb-neutral-800));
}

/* --- Auth pages (login/signup/password reset): centered branded card,
   no sidebar. See templates/allauth/layouts/base.html which sets
   body_class="eb-auth-page". --- */

.eb-auth-page {
  background: hsl(var(--eb-neutral-100));
}

.eb-auth-page .eb-main {
  max-width: 420px;
  margin: 3.5rem auto;
  background: #fff;
  border: 1px solid hsl(var(--eb-neutral-300));
  border-radius: 0.75rem;
  box-shadow: 0 4px 16px rgba(16, 24, 32, 0.08);
  padding: 2.25rem 2rem;
}

.eb-auth-page h1 {
  font-size: 1.3rem;
  margin-bottom: 1.25rem;
}

.eb-auth-page form p {
  margin-bottom: 1rem;
}

.eb-auth-page .btn {
  width: 100%;
}

/* --- Marketing homepage: full-bleed sections, no page padding (the
   template's own sections manage their own horizontal padding so a
   hero/feature band's background can run edge-to-edge). --- */
.eb-marketing-page .eb-main {
  padding: 0;
}
