/* ────────────────────────────────────────────────────────────────────────
   Xpensic — App shell layout
   Glass header, glass nav drawer, glass main container.
   ──────────────────────────────────────────────────────────────────────── */

.app {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: var(--header-h) 1fr;
  grid-template-areas:
    "header"
    "main";
  min-height: 100dvh;
  position: relative;
}

/* ─── Header ──────────────────────────────────────────────────────────── */
.app-header {
  grid-area: header;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-5);
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur-strong);
  backdrop-filter: var(--glass-blur-strong);
  border-bottom: 1px solid var(--glass-border);
  position: sticky;
  top: 0;
  z-index: 30;
  transition: background var(--dur-med) var(--ease-out),
              border-color var(--dur-med) var(--ease-out);
}

.app-header__spacer { flex: 1; }

/* Brand — the new XPENSIC lockup. The X+arrow mark comes from a
   cropped PNG (assets/brand/mark-light.png and mark-dark.png). The
    "Xpensic" wordmark and "Track expenses. Take control." tagline are
   rendered as live HTML so the tagline stays editable and renders
   with the same crisp typography the rest of the UI uses. */
.app-brand {
  display: inline-flex;
  align-items: flex-start;
  padding-top: 0;
  /* Slight negative margin so the wider lockup sits flush with the
     hamburger icon on the left without crowding the month picker. */
  margin-left: calc(-1 * var(--space-1));
  gap: var(--space-3);
  transition: transform var(--dur-med) var(--ease-spring);
  text-decoration: none;
  color: var(--color-text);
}

.app-brand:hover {
  transform: scale(1.02);
}

/* Show the right logo for the active theme. By default both variants
   are present in the DOM so the browser pre-decodes the inactive one
   and the swap is instant the moment data-theme flips. */
[data-theme="light"] .app-brand__logo--dark,
.app-brand__logo--dark { display: none; }
[data-theme="light"] .app-brand__logo--light { display: block; }
[data-theme="dark"] .app-brand__logo--light,
.app-brand__logo--light { display: none; }
[data-theme="dark"] .app-brand__logo--dark { display: block; }

/* Full SVG lockup (wordmark included). Sized by width with auto height
   so proportions stay true and the logo stays crisp on Retina. */
.app-brand__logo {
  width: 200px;
  height: auto;
  max-width: 100%;
  display: block;
  flex: 0 0 auto;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}

/* Tagline below the logo. */
.app-brand__type {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1;
}

.app-brand__tagline {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--brand-tagline, #475569);
  opacity: 0.85;
}

[data-theme="dark"] .app-brand__tagline {
  color: #94A3B8;
}

/* Intermediate breakpoints so the lockup stays balanced across
   tablet + phone widths. On phones we drop the tagline so the
   logo still fits comfortably. */
@media (max-width: 720px) {
  .app-brand__logo { width: 120px; }
  .app-brand__tagline { font-size: 10px; }
}
@media (max-width: 480px) {
  .app-brand__tagline { display: none; }
  .app-brand__logo { width: 110px; }
}

/* ─── Hamburger icon ──────────────────────────────────────────────────── */
.icon-btn__bars {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 18px;
  height: 14px;
}
.icon-btn__bars > span {
  display: block;
  width: 18px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform var(--dur-med) var(--ease-out),
              opacity var(--dur-med) var(--ease-out);
}
.nav-toggle[aria-expanded="true"] .icon-btn__bars > span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .icon-btn__bars > span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .icon-btn__bars > span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* ─── Nav drawer ──────────────────────────────────────────────────────── */
.app-nav {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--nav-w);
  max-width: 86vw;
  background: var(--glass-bg-strong);
  -webkit-backdrop-filter: var(--glass-blur-strong);
  backdrop-filter: var(--glass-blur-strong);
  border-right: 1px solid var(--glass-border);
  padding: 0 var(--space-3) var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  z-index: 50;
  transform: translateX(-100%);
  transition: transform var(--dur-slow) var(--ease-out);
  box-shadow: var(--shadow-lg);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.app-nav.is-open {
  transform: translateX(0);
}

.app-nav__profile {
  padding: 0;
  border-bottom: 1px solid var(--glass-border);
  margin-bottom: var(--space-1);
}

/* XPENSIC drawer brand — full lockup that fills the top of the
   drawer. The mark sits on the left, the wordmark + tagline stack
   to its right. Sized to feel anchored (not floating) at the top of
   the menu, with generous vertical padding so the menu list below
   has clear breathing room. The wordmark + tagline are always both
   visible (the tagline is the brand's voice, not a decorative
   flourish), and the tagline wraps to a second line on narrow
   drawers so the full sentence is never truncated. */
.app-nav__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  /* Anchored at the very top of the drawer — minimal top padding so the
     logo starts flush with the top edge and no space is wasted. Bottom
     padding gives breathing room above the profile card divider. */
  padding: var(--space-3) var(--space-2) var(--space-4);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--glass-border);
}

.app-nav__brand-mark {
  /* The full SVG lockup (wordmark included) — wider than tall, so we
     size by width and let height follow to preserve proportions. */
  width: 160px;
  height: auto;
  display: block;
  flex: 0 0 auto;
  filter: drop-shadow(0 2px 6px rgba(15, 23, 42, 0.18));
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
}

/* Theme-aware visibility swap, same pattern as the header. */
[data-theme="light"] .app-nav__brand-mark--dark,
.app-nav__brand-mark--dark {
  display: none;
}
[data-theme="light"] .app-nav__brand-mark--light {
  display: block;
}
[data-theme="dark"] .app-nav__brand-mark--light,
.app-nav__brand-mark--light {
  display: none;
}
[data-theme="dark"] .app-nav__brand-mark--dark {
  display: block;
}

/* Stacked wordmark + tagline. Wordmark is the primary read; tagline
   sits below at a smaller, lighter weight for hierarchy. The
   container takes the remaining width (mark is flex: 0 0 auto) so
   the wordmark can grow into the available space. */
.app-nav__brand-type {
  display: flex;
  flex-direction: column;
  gap: 4px;
  line-height: 1.15;
  min-width: 0;
  flex: 1 1 auto;
}

.app-nav__brand-wordmark {
  font-family: var(--font-display, "Poppins"), "Inter", system-ui, sans-serif;
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.02em;
  color: var(--brand-wordmark, #0F172A);
  line-height: 1;
}

.app-nav__brand-tagline {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--brand-tagline, #475569);
  opacity: 0.85;
  /* Allow the tagline to wrap on narrow drawers — never truncate. */
  line-height: 1.25;
  word-wrap: break-word;
  overflow-wrap: break-word;
}

[data-theme="dark"] .app-nav__brand-wordmark {
  color: #F8FAFC;
}
[data-theme="dark"] .app-nav__brand-tagline {
  color: #94A3B8;
}

/* On the very narrowest drawers, shrink the mark + wordmark so
   the brand never pushes the profile card out of view. The tagline
   keeps its full width because wrapping handles it gracefully. */
@media (max-width: 320px) {
  .app-nav__brand-mark { width: 100px; height: auto; }
  .app-nav__brand-tagline { font-size: 10px; }
}
.app-nav__profile-card {
  /* Wraps the profile link so it shares padding/visual rhythm without
     leaking layout into the surrounding nav shell. The element is a
     plain block — no border of its own — because the parent
     `.app-nav__profile` already carries the divider. */
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.app-nav__profile-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
  transition: background var(--dur-med) var(--ease-out);
}
.app-nav__profile-link:hover {
  background: var(--glass-bg-soft);
}
.app-nav__profile-link.is-active {
  background: var(--color-primary-soft);
}
.app-nav__profile-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-surface-2);
  flex: 0 0 auto;
  object-fit: cover;
  border: 2px solid var(--glass-border-strong);
}
.app-nav__profile-id {
  min-width: 0;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}
.app-nav__profile-name {
  font-weight: 600;
  font-size: var(--text-md);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-nav__profile-phone {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.app-nav__profile-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  color: var(--color-text-faint);
  opacity: 0.7;
  transition: transform var(--dur-med) var(--ease-out),
              opacity var(--dur-med) var(--ease-out);
}
.app-nav__profile-link:hover .app-nav__profile-chevron {
  opacity: 1;
  transform: translateX(2px);
}
.app-nav__profile-chevron svg {
  width: 100%;
  height: 100%;
  display: block;
}

.nav-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 10px var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-weight: 500;
  font-family: inherit;
  font-size: var(--text-sm);
  background: transparent;
  border: none;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-med) var(--ease-out),
              color var(--dur-med) var(--ease-out),
              transform var(--dur-med) var(--ease-out);
  position: relative;
}
.nav-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  bottom: 8px;
  width: 3px;
  background: var(--color-primary);
  border-radius: 0 4px 4px 0;
  opacity: 0;
  transform: scaleY(0.5);
  transition: opacity var(--dur-med) var(--ease-out),
              transform var(--dur-med) var(--ease-out);
}
.nav-link:hover {
  background: var(--glass-bg-soft);
  color: var(--color-text);
  transform: translateX(2px);
}
.nav-link.is-active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-weight: 600;
  border-left: 3px solid var(--color-primary);
  color: var(--color-text);
}
.nav-link.is-active::before {
  opacity: 1;
  transform: scaleY(1);
}

/* Nav link icon — crisp 20px glyph that inherits the link colour and
   stays vertically centred with the label. Sized for a comfortable
   touch target on mobile while staying subtle on desktop. */
.nav-link__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  color: inherit;
  opacity: 0.85;
}
.nav-link__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}
.nav-link.is-active .nav-link__icon {
  color: var(--color-primary);
  opacity: 1;
}
.nav-link__label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sign-out nav link — sits at the bottom of the nav list. Uses the
   danger colour on hover so it reads as a destructive action without
   competing with the primary nav links. */
.nav-link--signout {
  margin-top: var(--space-1);
  color: var(--color-text-muted);
}
.nav-link--signout:hover,
.nav-link--signout:focus-visible {
  background: var(--color-danger-soft, rgba(239, 68, 68, 0.12));
  color: var(--color-danger, #ef4444);
  outline: none;
}
.nav-link--signout .nav-link__icon {
  color: inherit;
}

.nav-link--profile { display: none; }

/* ─── Quick actions ──────────────────────────────────────────────────── */
.app-nav__quick {
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--glass-border);
}
.app-nav__section-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-faint);
  padding: 0 var(--space-2) var(--space-2);
}
.app-nav__quick-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2);
}
.app-nav__quick-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: var(--space-3) var(--space-2);
  border-radius: var(--radius-lg);
  border: 1px solid var(--glass-border);
  background: var(--glass-bg-soft);
  color: var(--color-text);
  font-family: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  text-align: center;
  cursor: pointer;
  transition: background var(--dur-med) var(--ease-out),
              border-color var(--dur-med) var(--ease-out),
              transform var(--dur-med) var(--ease-out),
              box-shadow var(--dur-med) var(--ease-out);
}
.app-nav__quick-btn:hover {
  background: var(--glass-bg);
  border-color: var(--glass-border-strong);
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}
.app-nav__quick-btn:active {
  transform: translateY(0.5px);
}
.app-nav__quick-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  color: var(--color-primary);
}
.app-nav__quick-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}
.app-nav__quick-label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Nav links section — grows to fill remaining space so the footer
   stays pinned to the bottom. */
.app-nav__links {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
}
.app-nav__links::-webkit-scrollbar { display: none; }

.app-nav__footer {
  margin-top: auto;
  color: var(--color-text-muted);
  padding: var(--space-3) var(--space-2) var(--space-2);
  border-top: 1px solid var(--glass-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  flex-shrink: 0;
}
.app-nav__encrypted {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-text-faint);
}
.app-nav__encrypted-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  color: var(--color-success);
}
.app-nav__encrypted-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* ─── Scrim ───────────────────────────────────────────────────────────── */
.nav-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  z-index: 40;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-med) var(--ease-out);
}
.nav-scrim.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* ─── Main + view container ───────────────────────────────────────────── */
.app-main {
  grid-area: main;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-5) var(--space-5) calc(var(--space-7) + 80px);
  scroll-behavior: smooth;
}

.app-main:focus { outline: none; }

.view {
  max-width: var(--content-max);
  margin: 0 auto;
  animation: view-fade-in var(--dur-med) var(--ease-out);
}

@keyframes view-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ─── Toast region ────────────────────────────────────────────────────── */
.toast-region {
  position: fixed;
  inset: auto var(--space-5) var(--space-5) auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: 100;
  pointer-events: none;
}

/* ─── Lock screen ─────────────────────────────────────────────────────── */
body.app-locked .app { display: none; }

/* ─── Mobile layout tightening ────────────────────────────────────────── */
@media (max-width: 720px) {
  .app-main { padding: var(--space-4) var(--space-4) 100px; }
  .app-header { padding: 0 var(--space-4); }

  /* On phones the drawer is narrower, so tighten the brand + profile
     spacing and let the quick actions breathe without crowding. */
  .app-nav__brand { padding: var(--space-3) var(--space-1) var(--space-3); }
  .app-nav__brand-mark { width: 140px; }
  .app-nav__profile-link { padding: var(--space-2) var(--space-1); }
  .app-nav__quick-btn { padding: 10px var(--space-2); }
}
