/* ==========================================================================
   Layout — auth shell (split screen) and admin shell (sidebar + topbar)
   ========================================================================== */

/* ---- Auth shell ----
   One continuous hero backdrop with a single full-bleed animated .node-mesh
   graphic behind both halves — there is no seam to hide because there's only
   one background. Follows theme like the rest of the app (--color-canvas/
   --color-ink, not the always-dark --color-brand-panel/-ink used by the
   sidebar's brand mark) — light mode gets a light near-white backdrop with a
   deeper-gold mesh (--mesh-dot-rgb, see tokens.css) for contrast; dark mode
   keeps the near-black backdrop with the bright brand yellow. The branding
   copy sits directly on it on the left; the actual form floats above it as
   an elevated .auth-form card on the right, like a hero image with a login
   card over it, rather than a second flat-filled half. */
.auth-shell {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  min-height: 100vh;
  background: var(--color-canvas);
  overflow: hidden;
}

.auth-shell__panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--space-8);
  color: var(--color-ink);
}

.auth-shell__panel-mark {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
}

.auth-shell__panel-mark img {
  height: 2.25rem;
  width: auto;
  display: block;
}

/* Brand mark: swap logo variant for theme. */
.brand-mark {
  display: inline-flex;
  align-items: center;
}

.brand-mark img {
  height: 1.75rem;
  width: auto;
  display: block;
}

/* Same swap applies to the auth hero's .auth-shell__panel-mark, now that its
   backdrop follows theme instead of always being dark. */
.brand-mark .logo--light,
.auth-shell__panel-mark .logo--light {
  display: none;
}

[data-theme="dark"] .brand-mark .logo--light,
[data-theme="dark"] .auth-shell__panel-mark .logo--light {
  display: block;
}

[data-theme="dark"] .brand-mark .logo--dark,
[data-theme="dark"] .auth-shell__panel-mark .logo--dark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .brand-mark .logo--light,
  :root:not([data-theme="light"]) .auth-shell__panel-mark .logo--light {
    display: block;
  }
  :root:not([data-theme="light"]) .brand-mark .logo--dark,
  :root:not([data-theme="light"]) .auth-shell__panel-mark .logo--dark {
    display: none;
  }
}

.auth-shell__panel-copy {
  position: relative;
  z-index: 1;
  max-width: 26rem;
}

.auth-shell__panel-copy h2 {
  color: var(--color-ink);
  font-size: 1.75rem;
  margin-bottom: var(--space-4);
}

.auth-shell__panel-copy p {
  color: var(--color-ink-muted);
  font-size: var(--text-h3);
  line-height: var(--leading-snug);
}

.auth-shell__panel-quote {
  position: relative;
  z-index: 1;
  padding-top: var(--space-5);
  border-top: 0.0625rem solid var(--color-border);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.auth-shell__panel-quote strong {
  display: block;
  color: var(--color-ink);
  font-weight: 600;
  margin-top: var(--space-2);
}

.auth-shell__form-side {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
}

.auth-shell__theme-toggle {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  z-index: 1;
}

/* The form floats as an elevated card over the shared hero backdrop. */
.auth-form {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 25rem;
  background: var(--color-surface);
  border: 0.0625rem solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-7);
}

.auth-form__header {
  margin-bottom: var(--space-7);
}

.auth-form__header .eyebrow {
  margin-bottom: var(--space-4);
}

.auth-form__header p {
  margin-top: var(--space-2);
  color: var(--color-ink-muted);
}

.auth-form__fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.auth-form__submit {
  margin-top: var(--space-6);
}

.auth-form__divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-6) 0;
  color: var(--color-ink-faint);
  font-size: var(--text-small);
}

.auth-form__divider::before,
.auth-form__divider::after {
  content: "";
  flex: 1;
  border-top: 0.0625rem solid var(--color-border);
}

.auth-form__footer {
  text-align: center;
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

.auth-form__footer a {
  font-weight: 600;
  color: var(--color-accent-ink);
}

.auth-form__footer a:hover {
  text-decoration: underline;
}

.auth-form__legal {
  margin-top: var(--space-8);
  font-size: var(--text-micro);
  color: var(--color-ink-faint);
  text-align: center;
}

@media (max-width: 61.25rem) {
  .auth-shell {
    grid-template-columns: 1fr;
  }
  .auth-shell__panel {
    display: none;
  }
}

/* ---- Admin shell ---- */
.app-shell {
  display: grid;
  grid-template-columns: 16.5rem 1fr;
  min-height: 100vh;
}

/* data-nav-toggle (admin_topbar.html) sets body[data-sidebar] via app.js's
   initMobileNav() to an explicit "shown"/"hidden" value — not a class whose
   meaning flips depending on which breakpoint's media query happens to
   match. That flip approach broke down right at the 61.25rem boundary
   (980px): two rules with identical specificity, one per breakpoint,
   assigned opposite meanings to the same class, so at exactly the boundary
   width tiny environmental differences (e.g. a scrollbar appearing after
   toggling changes the layout height) could make either rule "win",
   producing an inconsistent/corrupted layout. An explicit value is
   unambiguous at every width, including exactly at the boundary. */
body[data-sidebar="hidden"] .app-shell {
  grid-template-columns: 1fr;
}

body[data-sidebar="hidden"] .sidebar {
  display: none;
}

body[data-sidebar="shown"] .app-shell {
  grid-template-columns: 16.5rem 1fr;
}

body[data-sidebar="shown"] .sidebar {
  display: flex;
}

.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-right: 0.0625rem solid var(--color-border);
  padding: var(--space-5) var(--space-4);
}

.sidebar__mark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-2);
  margin-bottom: var(--space-7);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-h3);
  color: var(--color-ink);
}

.sidebar__mark-link {
  display: inline-flex;
  align-items: center;
}

.sidebar__section-label {
  padding: 0 var(--space-2);
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-ink-faint);
}

.sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.sidebar__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--text-small);
  font-weight: 500;
  color: var(--color-ink-muted);
  transition: background var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
}

.sidebar__link svg {
  width: 1.125rem;
  height: 1.125rem;
  flex-shrink: 0;
}

.sidebar__link:hover {
  background: var(--color-canvas-inset);
  color: var(--color-ink);
}

.sidebar__link--active {
  background: var(--color-accent-soft);
  color: var(--color-accent-ink);
}

.sidebar__link-badge {
  margin-left: auto;
}

.sidebar__nav-group + .sidebar__nav-group {
  margin-top: var(--space-6);
}

.sidebar__footer {
  margin-top: auto;
  padding-top: var(--space-4);
  border-top: 0.0625rem solid var(--color-border);
}

.sidebar__user {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  cursor: pointer;
}

/* Scoped to the topbar's account-menu button only (not the sidebar-footer's
   non-interactive user block) -- same hover feedback as its neighbors, the
   bell and theme-toggle buttons (.btn--ghost:hover, components.css). Base
   background set here too (not left to a native-button default or an
   inline style), so it doesn't out-specificity the :hover rule below. */
.topbar__actions .sidebar__user {
  background: none;
}

.topbar__actions .sidebar__user:hover {
  background: var(--color-canvas-inset);
}

.sidebar__user-meta {
  min-width: 0;
}

.sidebar__user-meta strong {
  display: block;
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--color-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar__user-meta span {
  display: block;
  font-size: var(--text-micro);
  color: var(--color-ink-faint);
}

.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  height: 4rem;
  padding: 0 var(--space-6);
  background: var(--color-canvas);
  background: color-mix(in srgb, var(--color-canvas) 88%, transparent);
  backdrop-filter: blur(0.5rem);
  border-bottom: 0.0625rem solid var(--color-border);
}

.topbar__crumbs {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-small);
  color: var(--color-ink-faint);
}

.topbar__crumbs strong {
  color: var(--color-ink);
  font-weight: 600;
}

.topbar__search {
  display: none;
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

/* Notification bell: slightly larger click target (44px, standard touch size)
   than the shared 2.5rem icon buttons. Scoped to the bell's .menu wrapper so
   the theme toggle and avatar keep their size. */
#notifications-menu > .btn--icon {
  width: 2.75rem;
  height: 2.75rem;
}

@media (min-width: 56.25rem) {
  .topbar__search {
    display: flex;
    position: relative;
    align-items: center;
    gap: var(--space-2);
    width: 20rem;
    height: 2.25rem;
    padding: 0 var(--space-3);
    border-radius: var(--radius-md);
    background: var(--color-canvas-inset);
    color: var(--color-ink-faint);
    font-size: var(--text-small);
  }

  .topbar__search svg {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
  }

  .topbar__search kbd {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: var(--text-micro);
    padding: 0.125rem var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    border: 0.0625rem solid var(--color-border);
  }
}

.page {
  flex: 1;
  padding: var(--space-6);
}

.page__header {
  position: relative;
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
  border-bottom: 0.0625rem solid var(--color-border);
}

.page__header-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.page__title-group h1 {
  margin-bottom: var(--space-1);
}

.page__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.page__toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.page__filters {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.page__filters .input,
.page__filters .select {
  height: 2.25rem;
  width: 15rem;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.content-grid {
  container-type: inline-size;
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

/* Container query (not a viewport media query) — reacts to this element's
   own rendered width. A viewport-width breakpoint can be wrong here: the
   sidebar being open/collapsed, browser zoom, or root font-size settings
   can all make .content-grid's actual available width diverge from what a
   fixed viewport threshold assumes, which previously let the two cards get
   squeezed into unreadable, near-zero-width columns instead of stacking. */
@container (max-width: 40rem) {
  .content-grid {
    grid-template-columns: 1fr;
  }
}

.activity-list {
  display: flex;
  flex-direction: column;
}

.activity-item {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 0.0625rem solid var(--color-border);
}

.activity-item:last-child {
  border-bottom: none;
}

.activity-item__body p {
  font-size: var(--text-small);
  color: var(--color-ink);
}

.activity-item__body time {
  display: block;
  margin-top: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  color: var(--color-ink-faint);
}

.source-breakdown {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.source-breakdown__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.source-breakdown__row-label {
  flex: 1;
  min-width: 0;
  font-size: var(--text-small);
}

.source-breakdown__row-label span {
  display: block;
  font-size: var(--text-micro);
  color: var(--color-ink-faint);
}

.source-breakdown__row-value {
  font-family: var(--font-mono);
  font-size: var(--text-small);
  color: var(--color-ink-muted);
}

@media (max-width: 75rem) {
  .stat-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 61.25rem) {
  /* Narrow-screen default: hidden. body[data-sidebar] (set only once the
     user actually clicks the toggle) overrides this unambiguously at any
     width via the higher-specificity attribute rules above — no separate
     override needed here. */
  .app-shell {
    grid-template-columns: 1fr;
  }
  .sidebar {
    display: none;
  }
}

.upload-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
  padding: var(--space-8);
  border: 0.09375rem dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  background: var(--color-canvas-inset);
}

.upload-dropzone__icon {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background: var(--color-accent-soft);
  color: var(--color-accent-ink);
  display: flex;
  align-items: center;
  justify-content: center;
}
