/* ============================================================
   Los 1000 Asados — "Brasas" design system substrate.
   Single stylesheet: self-hosted fonts + tokens + Bootstrap 5.3
   dark mapping. Ported from design-system/tokens.css (source of
   truth) per ADR-0001. Dark-first, mobile-first.
   Per-screen reskins layer on top of this file.
   ============================================================ */

/* ---- Self-hosted fonts (fontsource woff2, latin subset covers es-AR).
   Chivo = display + tabular numerals; Archivo = UI + body. Only the
   weights the type scale uses are shipped. `swap` avoids invisible text. */
@font-face {
  font-family: 'Chivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/chivo-latin-700-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Chivo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('/fonts/chivo-latin-800-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Chivo';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('/fonts/chivo-latin-900-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/archivo-latin-400-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/archivo-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/fonts/archivo-latin-600-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/archivo-latin-700-normal.woff2') format('woff2');
}

/* Space Grotesk = the brand/wordmark typeface (identity guide). Used only for
   the "Splitfire" wordmark + landing hero lockup, NOT for app UI/headings
   (those stay Chivo/Archivo). Latin subset covers es-AR. */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/space-grotesk-latin-500-normal.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-latin-700-normal.woff2') format('woff2');
}

/* ============================================================
   Brasas tokens — ported verbatim from design-system/tokens.css.
   ============================================================ */
:root {
  /* ---- Color: surfaces (warm charcoal, never pure black) ---- */
  --carbon:   #17120F;   /* app background */
  --carbon-2: #1F1815;   /* subtle raised background */
  --ceniza:   #2A2320;   /* card / sheet surface */
  --ceniza-2: #362D28;   /* hover, strong border */

  /* ---- Color: text & lines ---- */
  --humo:   #6B615B;     /* muted text, hairline borders */
  --humo-2: #9A8E85;     /* secondary text */
  --hueso:  #F2E9DE;     /* primary text (salt / bone) */

  /* ---- Color: ember accent (the one bold gesture) ---- */
  --brasa: #FF5A1F;      /* primary accent */
  --fuego: #E8340C;      /* deep fire */
  --ember: linear-gradient(135deg, #FF7A2F 0%, #E8340C 100%);
  --glow:  0 0 24px rgba(255, 90, 31, 0.35);

  /* ---- Color: semantic balances ---- */
  --chimi:     #7BA05B;               /* creditor — "te deben" */
  --chimi-dim: rgba(123, 160, 91, .14);
  --clay:      #D65A3F;               /* debtor — "debés" (warm, not alarm) */
  --clay-dim:  rgba(214, 90, 63, .16);

  /* ---- Typography ---- */
  --font-display: 'Chivo', 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-ui:      'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-brand:   'Space Grotesk', 'Chivo', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* type scale (mobile) */
  --t-amount: 800 56px/1.0 var(--font-display);   /* hero amount */
  --t-h1:     700 24px/1.15 var(--font-ui);
  --t-h2:     700 19px/1.2 var(--font-ui);
  --t-body:   400 16px/1.45 var(--font-ui);
  --t-meta:   500 13px/1.3 var(--font-ui);
  --t-eyebrow:700 12px/1 var(--font-ui);          /* + letter-spacing .09em, uppercase */
  --num-feat: "tnum" 1, "lnum" 1;                 /* tabular lining numerals */

  /* ---- Radius ---- */
  --r-sm: 10px;
  --r-md: 16px;
  --r-lg: 22px;
  --r-full: 999px;

  /* ---- Spacing (4pt scale) ---- */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 20px; --s-6: 24px; --s-8: 32px; --s-10: 40px;

  /* ---- Elevation ---- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow-2: 0 10px 28px rgba(0, 0, 0, .48);

  /* ---- Layout ---- */
  --bar-h: 56px;         /* top context bar / bottom nav height */
  --page-pad: 20px;
  --thumb-zone: 24px;    /* safe padding above bottom action */

  /* ---- Breakpoints (match Bootstrap 5.3 defaults) ---- */
  --bp-sm: 576px;
  --bp-md: 768px;   /* asados list: 1 → 2 columns */
  --bp-lg: 992px;   /* the switch: bottom-nav/offcanvas → navbar/modal; detail → 2-col */
  --bp-xl: 1200px;

  /* ---- Content widths ---- */
  --w-flow: 720px;   /* single-flow screens (home, expense form) centered column */
  --w-wide: 1120px;  /* screens that use the width (event detail, asados list) */
}

/* ============================================================
   Bootstrap 5.3 mapping — repaint Bootstrap with Brasas.
   Applied globally: the whole app runs data-bs-theme="dark".
   Keeps Bootstrap's grid / navbar / offcanvas / modal, no new
   framework, no build step. (See tokens.css mapping block.)
   ============================================================ */
:root,
[data-bs-theme="dark"] {
  --bs-body-bg:            var(--carbon);
  --bs-body-color:         var(--hueso);
  --bs-secondary-color:    var(--humo-2);
  --bs-secondary-bg:       var(--carbon-2);
  --bs-tertiary-color:     var(--humo);
  --bs-tertiary-bg:        var(--carbon-2);
  --bs-border-color:       var(--ceniza-2);
  --bs-emphasis-color:     var(--hueso);

  --bs-primary:            var(--brasa);
  --bs-primary-rgb:        255, 90, 31;

  --bs-body-font-family:   var(--font-ui);
  --bs-border-radius:      var(--r-md);
  --bs-border-radius-sm:   var(--r-sm);
  --bs-border-radius-lg:   var(--r-lg);

  /* link color rides the ember accent */
  --bs-link-color:            var(--brasa);
  --bs-link-color-rgb:        255, 90, 31;
  --bs-link-hover-color:      #FF7A2F;
  --bs-link-hover-color-rgb:  255, 122, 47;

  /* surfaces: --ceniza for card / offcanvas / modal / dropdown */
  --bs-card-bg:            var(--ceniza);
  --bs-card-cap-bg:        var(--ceniza-2);
  --bs-card-border-color:  var(--ceniza-2);
  --bs-modal-bg:           var(--ceniza);
  --bs-offcanvas-bg:       var(--ceniza);
  --bs-dropdown-bg:        var(--ceniza);
  --bs-dropdown-link-hover-bg: var(--ceniza-2);
}

/* ============================================================
   Bootstrap 5.3 component repaint.
   Bootstrap compiles the "primary" component colors (btn, bg, text)
   to literal hex from Sass at build time, so remapping --bs-primary
   alone leaves buttons/navbar Bootstrap-blue. With no Sass rebuild
   (the no-build rule), repaint the component-level vars/props here.
   ============================================================ */
.btn-primary {
  --bs-btn-color:               var(--carbon);
  --bs-btn-bg:                  var(--brasa);
  --bs-btn-border-color:        var(--brasa);
  --bs-btn-hover-color:         var(--carbon);
  --bs-btn-hover-bg:            #FF7A2F;
  --bs-btn-hover-border-color:  #FF7A2F;
  --bs-btn-active-color:        var(--hueso);
  --bs-btn-active-bg:           var(--fuego);
  --bs-btn-active-border-color: var(--fuego);
  --bs-btn-disabled-color:      var(--carbon);
  --bs-btn-disabled-bg:         var(--brasa);
  --bs-btn-disabled-border-color: var(--brasa);
}
.btn-outline-primary {
  --bs-btn-color:               var(--brasa);
  --bs-btn-border-color:        var(--brasa);
  --bs-btn-hover-color:         var(--carbon);
  --bs-btn-hover-bg:            var(--brasa);
  --bs-btn-hover-border-color:  var(--brasa);
  --bs-btn-active-color:        var(--carbon);
  --bs-btn-active-bg:           var(--brasa);
  --bs-btn-active-border-color: var(--brasa);
  --bs-btn-disabled-color:      var(--brasa);
}
.bg-primary       { background-color: var(--brasa) !important; }
.text-primary     { color: var(--brasa) !important; }
.text-bg-primary  { color: var(--carbon) !important; background-color: var(--brasa) !important; }
.border-primary   { border-color: var(--brasa) !important; }
.link-primary     { color: var(--brasa) !important; }
.link-primary:hover,
.link-primary:focus { color: #FF7A2F !important; }
.badge.bg-primary { color: var(--carbon); }
.nav-pills {
  --bs-nav-pills-link-active-bg:    var(--brasa);
  --bs-nav-pills-link-active-color: var(--carbon);
}
.list-group {
  --bs-list-group-active-bg:           var(--brasa);
  --bs-list-group-active-border-color: var(--brasa);
  --bs-list-group-active-color:        var(--carbon);
}
.progress { --bs-progress-bar-bg: var(--brasa); }
.form-range::-webkit-slider-thumb { background-color: var(--brasa); }
.form-range::-moz-range-thumb     { background-color: var(--brasa); }

/* Neutral secondary/tertiary actions — warm ash, never Bootstrap's cold grey.
   One canonical style for every cancel / "Volver" action (#153 F3/F4);
   same root repaint applied to the secondary badge/pill. */
.btn-secondary {
  --bs-btn-color:               var(--hueso);
  --bs-btn-bg:                  var(--ceniza);
  --bs-btn-border-color:        var(--ceniza-2);
  --bs-btn-hover-color:         var(--hueso);
  --bs-btn-hover-bg:            var(--ceniza-2);
  --bs-btn-hover-border-color:  var(--humo);
  --bs-btn-active-color:        var(--hueso);
  --bs-btn-active-bg:           var(--ceniza-2);
  --bs-btn-active-border-color: var(--humo);
  --bs-btn-disabled-color:      var(--humo);
  --bs-btn-disabled-bg:         var(--ceniza);
  --bs-btn-disabled-border-color: var(--ceniza-2);
}
.btn-outline-secondary {
  --bs-btn-color:               var(--humo-2);
  --bs-btn-border-color:        var(--ceniza-2);
  --bs-btn-hover-color:         var(--hueso);
  --bs-btn-hover-bg:            var(--ceniza-2);
  --bs-btn-hover-border-color:  var(--humo);
  --bs-btn-active-color:        var(--hueso);
  --bs-btn-active-bg:           var(--ceniza-2);
  --bs-btn-active-border-color: var(--humo);
  --bs-btn-disabled-color:      var(--humo);
}
.badge.bg-secondary,
.badge.text-bg-secondary {
  color: var(--hueso);
  background-color: var(--ceniza-2) !important;
}

/* "Continuar con Google": a light neutral button, like Google's own light variant, so it
   reads as a live action on the carbon substrate. Not an outline: the muted outline styles
   (outline-secondary / Bootstrap's outline-dark) look disabled on this palette. */
.btn-google {
  --bs-btn-color:               var(--carbon);
  --bs-btn-bg:                  var(--hueso);
  --bs-btn-border-color:        var(--hueso);
  --bs-btn-hover-color:         var(--carbon);
  --bs-btn-hover-bg:            #FFFFFF;
  --bs-btn-hover-border-color:  #FFFFFF;
  --bs-btn-active-color:        var(--carbon);
  --bs-btn-active-bg:           #E4DACE;
  --bs-btn-active-border-color: #E4DACE;
  --bs-btn-disabled-color:      var(--humo);
  --bs-btn-disabled-bg:         var(--ceniza-2);
  --bs-btn-disabled-border-color: var(--ceniza-2);
  font-weight: 600;
}
.btn-google .bi-google { color: #4285F4; }

/* Card headers: one subtle treatment everywhere (#153 F2). No ember header
   bars — ember is reserved for actions; the header rides the ceniza cap token. */
.card-header {
  padding: var(--s-4) var(--s-5);
  font-weight: 600;
  color: var(--hueso);
}

/* ============================================================
   Base substrate
   ============================================================ */
body {
  background-color: var(--bs-body-bg);
  color: var(--bs-body-color);
  font-family: var(--font-ui);
  min-height: 100vh;
}

/* Headings use the display face; keep Bootstrap's sizing. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.navbar-brand,
.display-1, .display-2, .display-3, .display-4, .display-5, .display-6 {
  font-family: var(--font-display);
}

/* Money / numeric figures: tabular lining numerals so columns align. */
.tabular-nums,
.amount,
.money {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: var(--num-feat);
}

/* Ember focus ring across inputs/controls. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus,
.btn:focus-visible {
  border-color: var(--brasa);
  box-shadow: 0 0 0 0.2rem rgba(255, 90, 31, 0.30);
}
.form-check-input:checked {
  background-color: var(--brasa);
  border-color: var(--brasa);
}

.form-label {
  font-weight: 500;
  margin-bottom: 0.5rem;
}

/* Badges + buttons keep a light interaction transition. */
.btn {
  transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.badge {
  font-weight: 500;
  padding: 0.35em 0.65em;
}

/* Neutral substrate for the legacy landing hero until it is reskinned
   (see map Fog: home = active-asado). Ember wash over carbon, no blue. */
.hero-section {
  background: radial-gradient(120% 140% at 50% 0%, var(--ceniza) 0%, var(--carbon) 60%);
  min-height: 500px;
  display: flex;
  align-items: center;
}
.hero-section h1 {
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
}

/* ---- Brand wordmark (identity guide) ---------------------------------
   "Splitfire" set in Space Grotesk with the "fire" syllable carrying the
   ember gradient. Reused by the nav brands and the landing hero lockup. */
.wordmark {
  font-family: var(--font-brand);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--hueso);
}
.wm-fire {
  background: linear-gradient(120deg, #FFB24D, #FF5A1F 45%, #E8340C);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Landing hero lockup: isotype (flame) + wordmark, mirroring the brand
   guide. Replaces the plain text heading so the home actually shows the logo. */
.hero-lockup {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 2vw, 18px);
  margin: 0 0 1rem;
  text-shadow: none;
}
.hero-lockup .hero-flame {
  width: clamp(48px, 8vw, 76px);
  height: auto;
  filter: drop-shadow(0 6px 20px rgba(232, 52, 12, 0.35));
}
.hero-lockup .wordmark {
  font-size: clamp(40px, 8vw, 66px);
  letter-spacing: -0.03em;
}

/* Landing hero headline: the real page heading, sits below the logo lockup.
   The lockup is the brand isotype; this line carries the voice ("El asado ya
   está. Las cuentas también."). */
.hero-headline {
  font-family: var(--font-brand);
  font-weight: 700;
  font-size: clamp(28px, 5vw, 44px);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--hueso);
  max-width: 18ch;
  margin-left: auto;
  margin-right: auto;
}

/* Landing feature cards: subtle lift on hover. */
.card.border-0 {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card.border-0:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-2) !important;
}
.feature-icon {
  transition: transform 0.3s ease;
}
.card.border-0:hover .feature-icon {
  transform: scale(1.1);
}
.navbar-brand img {
  transition: transform 0.3s ease;
}
.navbar-brand:hover img {
  transform: scale(1.05);
}

/* Dark scrollbar (Chromium). */
::-webkit-scrollbar {
  width: 10px;
}
::-webkit-scrollbar-track {
  background: var(--carbon-2);
}
::-webkit-scrollbar-thumb {
  background: var(--ceniza-2);
  border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--humo);
}

/* Alert entrance animation (kept from the previous stylesheet). */
.alert {
  animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
  from { opacity: 0; transform: translateY(-20px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ============================================================
   Toasts — flash notifications float over the page instead of
   pushing it down (#192). Two layers, so the page never reflows:
     · a lone .app-toast is `fixed` on its own and therefore
       costs no layout space even before app.js runs;
     · app.js then moves every .app-toast into #appToasts, where
       they stack in a flex column — two flashes at once is rare
       but they must not land on top of each other.
   ============================================================ */
.app-toasts {
  position: fixed;
  top: calc(var(--bar-h) + var(--s-2) + env(safe-area-inset-top, 0px));  /* clear of the top bar */
  left: 50%;
  transform: translateX(-50%);
  z-index: 1090;                 /* above the quick-add sheet (1080) */
  width: min(34rem, calc(100vw - 2 * var(--s-4)));
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  pointer-events: none;          /* the empty host must never eat clicks */
}

.app-toast {
  /* Standalone (JS off / before init): float on its own. */
  position: fixed;
  top: calc(var(--bar-h) + var(--s-2) + env(safe-area-inset-top, 0px));  /* clear of the top bar */
  left: 50%;
  transform: translateX(-50%);
  z-index: 1090;
  width: min(34rem, calc(100vw - 2 * var(--s-4)));
  margin: 0;
  box-shadow: var(--shadow-2);
  animation: toastInCentered 0.25s ease-out;
}

/* Inside the host the flex column owns placement. */
.app-toasts .app-toast {
  position: static;
  transform: none;
  width: auto;
  pointer-events: auto;
  animation: toastIn 0.25s ease-out;
}

@keyframes toastInCentered {
  from { opacity: 0; transform: translate(-50%, -12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes toastIn {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .app-toast,
  .app-toasts .app-toast {
    animation: none;
  }
}

/* ============================================================
   Navigation shell (Brasas).
   One shell, two faces chosen by Bootstrap display utilities:
     · desktop (>= lg): a single top navbar (.app-navbar).
     · mobile  (< lg):  a top context bar (.app-ctxbar) + a fixed
       bottom nav (.app-bottomnav) with a centered "+ Gasto" FAB.
   The bottom nav / FAB are bespoke; everything else rides Bootstrap.
   ============================================================ */

/* Shared navbar surface — carbon-2 with a hairline underline, never blue. */
.app-navbar {
  background-color: var(--carbon-2);
  border-bottom: 1px solid var(--ceniza-2);
  padding-top: var(--s-3);
  padding-bottom: var(--s-3);
}
.app-navbar .navbar-brand {
  color: var(--hueso);
  font-size: 1.05rem;
}
/* Public navbar links (collapsing menu). */
.app-navbar .nav-link {
  color: var(--humo-2);
  font-weight: 500;
}
.app-navbar .nav-link:hover,
.app-navbar .nav-link:focus {
  color: var(--hueso);
}

/* Desktop app links: pill fill on hover / active, ember icon when active. */
.app-navlinks {
  gap: var(--s-1);
  margin-left: var(--s-5);
}
.app-navlink {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-sm);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 600;
  color: var(--humo-2);
  text-decoration: none;
  transition: color .15s ease, background-color .15s ease;
}
/* The group switcher renders the navlink as a <button>; strip native chrome. */
button.app-navlink {
  border: 0;
  background-color: transparent;
  cursor: pointer;
}
.app-navlink:hover {
  color: var(--hueso);
  background-color: var(--ceniza);
}
.app-navlink.on {
  color: var(--hueso);
  background-color: var(--ceniza);
}
.app-navlink.on i {
  color: var(--brasa);
}

/* "+ Gasto" — the one bold gesture: ember pill (desktop inline button). */
.btn-gasto {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  background: var(--ember);
  color: #fff;
  border: 0;
  border-radius: var(--r-full);
  padding: 10px 20px;
  font-family: var(--font-ui);
  font-weight: 700;
  font-size: 15px;
  box-shadow: var(--glow);
  cursor: pointer;
  text-decoration: none;   /* it is often an <a> (landing CTAs) — never underline (#153 F1) */
  transition: transform .15s ease, box-shadow .15s ease;
}
.btn-gasto:hover {
  transform: translateY(-1px);
}
.btn-gasto:active {
  transform: translateY(0);
}

/* Account avatar button (shared desktop + mobile); no dropdown caret. */
.app-avatar {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: 50%;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  color: var(--hueso);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.app-avatar::after {
  display: none;
}
/* Google profile photo: fills the button, cropped square-to-circle. */
.app-avatar img,
.av-photo {
  display: block;
  width: 100%;
  height: 100%;
  flex: 0 0 auto;   /* the avatars are flex boxes: never let the photo be squeezed */
  border-radius: 50%;
  object-fit: cover;
}
/* The photo fills the initial's circle; clip it so nothing squares off the corners. The
   circle's tint stays underneath on purpose: if the photo fails to load (Google's CDN
   unreachable) the avatar is still a filled circle, not a hole. */
.participant-row .participant-av:has(.av-photo),
.bulk-av:has(.av-photo),
.qa-chip .qa-av:has(.av-photo) {
  overflow: hidden;
}
.app-avatar:hover {
  background: var(--ceniza-2);
}

/* ---- Mobile: top context bar ---- */
.app-ctxbar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--bar-h);
  padding: var(--s-3) var(--s-4);
  background: var(--carbon-2);
  border-bottom: 1px solid var(--ceniza-2);
}
.app-ctxbar-brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  color: var(--hueso);
  text-decoration: none;
  font-weight: 700;
}
.app-ctxbar-badge {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--ember);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--glow);
}
.app-ctxbar-title {
  font-family: var(--font-brand);
  font-size: 15px;
}

/* Mobile group switcher pill (multi-group only), sits in the context bar. */
.app-ctxswitch {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  max-width: 48vw;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: 999px;
  padding: 5px 12px;
  color: var(--hueso);
  font: 600 13px/1 var(--font-ui);
}
.app-ctxswitch:hover {
  background: var(--ceniza-2);
}
.app-ctxswitch > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.app-ctxswitch .bi-chevron-down {
  color: var(--humo-2);
}

/* ---- Mobile: fixed bottom nav + centered FAB ---- */
.app-bottomnav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1030;
  display: flex;
  align-items: center;
  justify-content: space-around;
  min-height: var(--bar-h);
  background: var(--carbon-2);
  border-top: 1px solid var(--ceniza-2);
  padding: var(--s-2) var(--s-3) calc(var(--s-2) + env(safe-area-inset-bottom, 0px));
}
.app-tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 4px 0;
  color: var(--humo);
  text-decoration: none;
  font-size: 11px;
  font-weight: 600;
  transition: color .15s ease;
}
.app-tab-ic {
  font-size: 19px;
}
.app-tab.on {
  color: var(--brasa);
}

/* FAB sits in a fixed-width center slot stretched to the bar height, so the
   button floats above the bar's top edge and its "Gasto" caption sits below. */
.app-fab-slot {
  flex: 0 0 68px;
  align-self: stretch;
  position: relative;
}
.app-fab {
  position: absolute;
  left: 50%;
  top: -24px;
  transform: translateX(-50%);
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--ember);
  color: #fff;
  border: 3px solid var(--carbon-2);
  box-shadow: var(--glow);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 26px;
  cursor: pointer;
  transition: transform .15s ease;
}
.app-fab:active {
  transform: translateX(-50%) scale(.94);
}
.app-fab-lbl {
  position: absolute;
  left: 50%;
  bottom: 3px;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 700;
  color: var(--brasa);
}

/* Reserve height so the fixed bottom nav never covers page content. */
.app-bottomnav-spacer {
  height: calc(var(--bar-h) + var(--s-4));
}

/* ============================================================
   Component: Expense row (events/details :: expenseRow)
   The logged-expenses list on the event detail — flat list of
   rows, not a table. Ember-tinted rubro glyph, payer meta, and a
   tabular amount. Actions sit inline on the right.
   ============================================================ */
.expense-list {
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  overflow: hidden;
}
.expense-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--ceniza-2);
}
.expense-row:last-child {
  border-bottom: 0;
}
.expense-row .expense-ico {
  width: 42px;
  height: 42px;
  border-radius: var(--r-sm);
  background: var(--carbon);
  color: var(--brasa);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex: 0 0 auto;
}
.expense-row .expense-mid {
  flex: 1;
  min-width: 0;
}
.expense-row .expense-cat {
  font-weight: 600;
  font-size: 16px;
}
.expense-row .expense-by {
  font-size: 13px;
  color: var(--humo-2);
  margin-top: 2px;
}
.expense-row .expense-by b {
  color: var(--hueso);
  font-weight: 600;
}
/* Fiado (open expense, no payer) tag in the expense list */
.expense-row .expense-fiado {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--brasa);
  background: rgba(255, 90, 31, .12);
  border-radius: 6px;
  padding: 1px 7px;
}
.expense-row .expense-amt {
  font: 700 18px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
.expense-row .expense-actions {
  display: flex;
  gap: var(--s-1);
  flex: 0 0 auto;
}
.expense-list-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: var(--s-3) var(--s-4) 0;
  font-weight: 700;
}
.expense-list-total .expense-amt {
  font: 800 20px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  color: var(--brasa);
}

/* ============================================================
   Component: Settlement (events/details :: settlement)
   The live split — a stat strip, diverging balance bars
   (chimichurri = owed, clay = owes) and the minimal transfers.
   ============================================================ */
/* Stat row (#177): viewer's "tu situación" hero + total / attendees / per-person.
   Full width above the Gastos | Movimientos columns. */
.stat-row {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--s-3);
  margin-bottom: var(--s-5);
}
.stat-card {
  min-width: 0;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  padding: var(--s-4);
}
.stat-card .k {
  font-size: 11px;
  color: var(--humo);
  text-transform: uppercase;
  letter-spacing: .05em;
}
.stat-card .v {
  font: 800 20px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  margin-top: var(--s-2);
}
/* the viewer's own card is the hero (ember wash) */
.stat-card.you {
  background: linear-gradient(180deg, rgba(255, 90, 31, .16), var(--ceniza));
  border-color: rgba(255, 90, 31, .35);
}
.you-amt {
  font: 800 24px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  margin-top: var(--s-2);
  display: flex;
  align-items: center;
  gap: 4px;
}
.you-amt.pos { color: var(--chimi); }
.you-amt.neg { color: var(--clay); }
.you-amt.none { color: var(--humo-2); }
.you-sub {
  font-size: 12px;
  color: var(--humo-2);
  margin-top: 4px;
}
.you-cashier {
  margin-top: var(--s-2);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.you-flow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  font-size: 13px;
  color: var(--humo-2);
}
.you-flow b {
  font: 800 17px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
}
.you-flow.in b { color: var(--chimi); }
.you-flow.out b { color: var(--clay); }
@media (max-width: 767.98px) {
  .stat-row {
    grid-template-columns: 1fr 1fr;
  }
  .stat-card.you {
    grid-column: 1 / -1;
  }
}
.settlement-subhead {
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--humo);
  margin: var(--s-5) 0 var(--s-3);
  font-weight: 700;
}
/* Cashier movements (#177): grouped "le entra" / "paga" rows — no balance bars.
   Rows are compact; the viewer's own row is ember-highlighted (.mine). */
.settle-heading {
  font: 700 18px/1.2 var(--font-display);
  display: flex;
  align-items: center;
  margin: 0 0 var(--s-3);
}
.mov {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-sm);
  padding: var(--s-2) var(--s-3);
  margin-bottom: var(--s-2);
  font-size: 15px;
}
.mov.mine {
  border-color: rgba(255, 90, 31, .5);
  background: rgba(255, 90, 31, .08);
}
.mov .mov-who {
  font-weight: 600;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mov .mov-arrow {
  color: var(--brasa);
  display: inline-flex;
}
.mov .mov-amt {
  margin-left: auto;
  font: 700 15px/1 var(--font-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mov-in .mov-amt { color: var(--chimi); }
/* The Cajero's checklist (who already paid them). A paid row steps back. */
.mov-check-form { display: contents; }
.mov-check {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  margin: -4px 0 -4px -6px;
  padding: 0;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--humo);
  font-size: 20px;
  cursor: pointer;
}
.mov-check:hover { color: var(--hueso); }
.mov-check:focus-visible { outline: 2px solid var(--brasa); outline-offset: 1px; }
.mov-check.is-static { cursor: default; }
.mov.paid .mov-check { color: var(--chimi); }
.mov.paid .mov-who { color: var(--humo-2); }
.mov.paid .mov-amt { color: var(--humo-2); text-decoration: line-through; }
.mov .mov-paid {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--chimi);
  background: var(--chimi-dim);
  padding: 2px 6px;
  border-radius: var(--r-full);
}
.settlement-subhead--split {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.settlement-subhead .mov-count {
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--humo-2);
}
.mov-out .mov-amt { color: var(--clay); }
.mov .mov-tag {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--brasa);
  background: rgba(255, 90, 31, .15);
  padding: 2px 6px;
  border-radius: var(--r-full);
}
.mov-sup {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}
.mov-sup .bi { color: var(--humo); }
.mov-cat {
  color: var(--humo);
  font-size: 12px;
}
.mov .mov-alias {
  color: var(--brasa);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.mov .mov-alias .bi { color: var(--humo); }

/* Collapsed per-person ledger (de-prioritised, #173 dir. B v3) */
.ledger {
  margin-top: var(--s-5);
  border-top: 1px solid var(--ceniza-2);
  padding-top: var(--s-3);
}
.ledger > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--humo);
}
.ledger-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-4);
  margin-top: var(--s-3);
}
.ledger-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2);
  padding: 5px 0;
  font-size: 14px;
}
.ledger-line.mine .ledger-nm {
  color: var(--brasa);
  font-weight: 700;
}
.ledger-nm {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ledger-amt {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}
.ledger-amt.pos { color: var(--chimi); }
.ledger-amt.neg { color: var(--clay); }
/* Media beca chip in the Liquidación ledger and in the viewer's own card (#192). */
.ledger-chip.beca {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: var(--r-full);
  background: rgba(255, 90, 31, .07);
  color: var(--humo-2);
  border: 1px dashed rgba(255, 90, 31, .55);
  white-space: nowrap;
}
.you-beca {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: var(--s-2);
  font-size: 12px;
  font-weight: 600;
  color: var(--humo-2);
}
/* fiado / donation summary tags */
.settle-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: calc(-1 * var(--s-2)) 0 var(--s-4);
}
.settle-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: var(--r-full);
}
.settle-tag b {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.settle-tag.fiado {
  background: rgba(255, 90, 31, .12);
  color: var(--brasa);
}
.settle-tag.donacion {
  background: var(--chimi-dim);
  color: var(--chimi);
}
/* neutral fiado-without-cashier nudge (never a blocker) + hub supplier note */
.settle-nudge,
.settle-note {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  border-radius: var(--r-sm);
  padding: var(--s-3) var(--s-4);
  margin-top: var(--s-4);
  font-size: 13px;
  line-height: 1.4;
}
.settle-nudge {
  background: rgba(255, 90, 31, .1);
  color: var(--humo-2);
}
.settle-nudge b {
  color: var(--brasa);
}
.settle-nudge .bi {
  color: var(--brasa);
}
.settle-note {
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  color: var(--humo-2);
  margin-top: var(--s-3);
}
.settle-note b {
  color: var(--hueso);
  font-variant-numeric: tabular-nums;
}
.settle-note .bi {
  color: var(--humo);
}

/* Fiado breakdown by supplier (#95): one line per Proveedor the cashier pays. */
.fiado-breakdown {
  margin: calc(-1 * var(--s-2)) 0 var(--s-4);
}
.fiado-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding: 6px 0;
  border-bottom: 1px solid var(--ceniza-2);
  font-size: 13px;
}
.fiado-line:last-child {
  border-bottom: 0;
}
.fiado-who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  min-width: 0;
}
.fiado-nm b {
  color: var(--hueso);
  font-weight: 700;
}
.fiado-cat {
  color: var(--humo);
  font-size: 12px;
}
.fiado-nosup {
  color: var(--humo-2);
  font-style: italic;
}
.fiado-alias {
  color: var(--brasa);
  font-variant-numeric: tabular-nums;
}
.fiado-alias .bi {
  color: var(--humo);
}
.fiado-amt {
  color: var(--hueso);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Quick-add hints + disabled/locked chip states (fiado supplier flow, #95). */
.qa-hint {
  font-size: 12px;
  color: var(--humo-2);
  margin-top: 6px;
}
.qa-chip-disabled,
.qa-cat-locked:disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* ============================================================
   Component: Quick-add expense sheet (expenses/quick-add :: sheet)
   The signature interaction, loaded via htmx into #quick-add-host.
   One sheet that reflows at the `lg` breakpoint — bottom offcanvas
   on mobile, centered modal on desktop — with a custom dimmed
   backdrop (no Bootstrap offcanvas/modal component). Alpine owns
   the ephemeral state; `x-show` toggles .qa-backdrop display.
   ============================================================ */
[x-cloak] { display: none !important; }

.qa-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1080;                     /* above the bottom nav / FAB */
  background: rgba(10, 7, 6, .6);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: flex-end;             /* mobile: sheet anchored to the bottom */
  justify-content: center;
}

/* MOBILE: bottom offcanvas (default) */
.qa-sheet {
  width: 100%;
  background: var(--carbon-2);
  border: 1px solid var(--ceniza-2);
  border-bottom: 0;
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -12px 40px rgba(0, 0, 0, .5);
  padding: 14px 20px 24px;
  max-height: 96vh;
  overflow-y: auto;
  animation: qa-rise .22s ease;
}
@keyframes qa-rise {
  from { transform: translateY(16px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

.qa-grabber {
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--ceniza-2);
  margin: 0 auto 12px;
}
.qa-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}
.qa-head .qa-ttl {
  font: 700 17px/1.2 var(--font-ui);
}
.qa-head .qa-x {
  color: var(--humo-2);
  font-size: 22px;
  line-height: 1;
  background: var(--ceniza);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ceniza-2);
  cursor: pointer;
}
.qa-ctx {
  font-size: 13px;
  color: var(--humo-2);
  margin-bottom: 4px;
}
.qa-ctx b { color: var(--brasa); font-weight: 600; }

/* Amount hero */
.qa-amount-wrap {
  text-align: center;
  padding: 14px 0 4px;
}
.qa-amount-field {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
}
.qa-amount-field .qa-cur {
  font: 800 30px/1 var(--font-display);
  color: var(--humo);
}
.qa-amount-input {
  font: 800 clamp(46px, 13vw, 60px)/1 var(--font-display);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -.01em;
  background: transparent;
  border: 0;
  color: var(--hueso);
  width: min(260px, 64vw);
  text-align: left;
  outline: none;
}
.qa-amount-input::placeholder { color: var(--humo); opacity: .6; }
.qa-underline {
  height: 3px;
  width: 56%;
  max-width: 220px;
  margin: 8px auto 0;
  background: var(--ember);
  border-radius: 3px;
  box-shadow: var(--glow);
}

/* Chip groups */
.qa-grp { margin-top: 16px; }
.qa-lbl {
  font: 700 12px/1 var(--font-ui);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--humo);
  margin-bottom: 10px;
}
.qa-strip {
  display: flex;
  gap: 9px;
  overflow-x: auto;
  padding-bottom: 4px;
}
.qa-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: 999px;
  padding: 6px 13px 6px 6px;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  flex: 0 0 auto;
  color: var(--hueso);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.qa-chip .qa-av {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: #1a1412;
  background: var(--humo-2);
  text-transform: uppercase;
}
.qa-chip.on {
  border-color: transparent;
  background: var(--ember);
  box-shadow: var(--glow);
  color: #fff;
}
.qa-chip.on .qa-av { background: rgba(255, 255, 255, .9); color: #B3350E; }

.qa-cat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: 12px;
  padding: 9px 14px;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  flex: 0 0 auto;
  color: var(--hueso);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.qa-cat.on {
  border-color: var(--brasa);
  background: rgba(255, 90, 31, .12);
  color: #fff;
}
.qa-cat-empty { cursor: default; color: var(--humo-2); font-weight: 500; }

.qa-save {
  width: 100%;
  margin-top: 18px;
  background: var(--ember);
  color: #fff;
  border: 0;
  border-radius: 999px;
  padding: 16px;
  font: 700 17px/1 var(--font-ui);
  box-shadow: var(--glow);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  cursor: pointer;
  transition: transform .12s ease, opacity .12s ease;
}
.qa-save:active { transform: scale(.99); }
.qa-save:disabled { opacity: .5; box-shadow: none; cursor: not-allowed; }

/* DESKTOP: centered modal */
@media (min-width: 992px) {
  .qa-backdrop { align-items: center; }
  .qa-sheet {
    max-width: 480px;
    border-radius: 22px;
    border-bottom: 1px solid var(--ceniza-2);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
    padding: 22px 26px 26px;
  }
  .qa-grabber { display: none; }
}

/* Shared small empty-state icon — muted humo, used by suppliers/invitations/
   categories/dashboard so every empty state reads the same (#153 F7). */
.empty-state-icon {
  font-size: 2rem;
  color: var(--humo);
  margin-bottom: var(--s-2);
}

/* ============================================================
   Component: Event detail (events/details)
   Brasas 2-col layout — a compact event header, then the gastos
   list (col-lg-7) beside a sticky settlement panel (col-lg-5),
   stacking to one column on mobile. Below the split: admin
   participant management and the danger zone.
   ============================================================ */
.detail-page {
  padding-bottom: var(--s-8);
}

/* header */
.detail-header {
  margin: var(--s-2) 0 var(--s-6);
}
.detail-back {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  color: var(--humo-2);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  margin-bottom: var(--s-4);
}
.detail-back:hover {
  color: var(--hueso);
}
.detail-header-main {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.detail-badge {
  width: 46px;
  height: 46px;
  border-radius: var(--r-sm);
  background: var(--ember);
  box-shadow: var(--glow);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  color: #fff;
  flex: 0 0 auto;
}
.detail-header-text {
  flex: 1;
  min-width: 0;
}
.detail-title {
  font: 800 26px/1.1 var(--font-display);
}
.detail-sub {
  font-size: 14px;
  color: var(--humo-2);
  margin-top: 3px;
}
.detail-edit {
  flex: 0 0 auto;
}
/* status chip in the detail title — mirrors the home hero tag (#155) */
.detail-status {
  display: inline-block;
  vertical-align: middle;
  margin-left: var(--s-2);
  font: 700 10px/1 var(--font-ui);
  letter-spacing: .07em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 999px;
}
.detail-status--active {
  color: #1a1412;
  background: var(--brasa);
}
.detail-status--closed {
  color: var(--humo-2);
  background: var(--ceniza-2);
}
.detail-status--planned {
  color: var(--hueso);
  background: transparent;
  border: 1px solid var(--ceniza-2);
}
/* admin status controls (close / reopen / plan) */
.detail-status-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: 0 0 var(--s-6);
}
.detail-status-actions form {
  margin: 0;
}

/* notes */
.detail-notes {
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  padding: var(--s-4);
  margin-bottom: var(--s-6);
  color: var(--humo-2);
}
.detail-notes .k {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--humo);
  font-weight: 700;
  margin-bottom: var(--s-2);
}

/* self-service attendance — "tu situación" voy/no voy (#186) */
.self-attend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-left: 3px solid var(--ceniza-2);
  border-radius: var(--r-md);
  padding: var(--s-4);
  margin-bottom: var(--s-6);
}
.self-attend--in {
  border-left-color: var(--chimi, #7BA05B);
}
.self-attend--out,
.self-attend--none {
  border-left-color: var(--humo);
}
.self-attend-state {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 600;
  color: var(--hueso);
}
.self-attend--in .self-attend-state i {
  color: var(--chimi, #7BA05B);
}
.self-attend--out .self-attend-state i,
.self-attend--none .self-attend-state i {
  color: var(--humo);
}
.self-attend-actions {
  display: flex;
  gap: var(--s-2);
}
.self-attend-actions form {
  margin: 0;
}

/* section titles (Gastos / Participantes) */
.detail-section-title {
  font-size: 13px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--humo);
  font-weight: 700;
  margin: 0 0 var(--s-3);
}
.detail-section {
  margin-top: var(--s-8);
}

/* settlement column — a bordered panel, sticky beside the gastos on desktop */
.settle-panel {
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  padding: var(--s-5);
}
@media (min-width: 992px) {
  .settle-col {
    position: sticky;
    top: 92px;                      /* clears the sticky top navbar */
  }
}

/* shared small empty-state (participants, settlement no-attendees / all-settled) */
.empty-state-small {
  text-align: center;
  padding: var(--s-6) var(--s-4);
  background: var(--carbon-2);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  color: var(--humo-2);
}

/* participants */
.participant-list {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.participant-hint {
  color: var(--humo-2);
  font-size: 13px;
  margin: 0 0 var(--s-3);
}
.participant-hint .bi {
  color: var(--brasa);
}
.participant-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-3);
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-sm);
  padding: var(--s-3) var(--s-4);
}
.participant-row .participant-av {
  width: 38px;
  height: 38px;
  border-radius: var(--r-full);
  background: var(--ember);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 15px;
  flex: 0 0 auto;
}
.participant-row .participant-nm {
  flex: 1;
  min-width: 0;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.participant-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 11px;
  border-radius: var(--r-full);
  white-space: nowrap;
  flex: 0 0 auto;
}
.participant-chip.went {
  background: var(--chimi-dim);
  color: var(--chimi);
}
.participant-chip.absent {
  background: var(--ceniza-2);
  color: var(--humo-2);
}
.participant-chip.cajero {
  background: rgba(255, 90, 31, .15);
  color: var(--brasa);
}
.participant-chip.invitado {
  background: var(--ceniza-2);
  color: var(--humo-2);
}
/* Media beca (#192): half a Parte, so a half-strength marker — the ember hue of
   the Cajero chip, but hollow and dashed, never a second solid chip on the row. */
.participant-chip.beca {
  background: rgba(255, 90, 31, .07);
  color: var(--hueso);
  border: 1px dashed rgba(255, 90, 31, .55);
  padding: 4px 10px;
}

/* Parte control (#192): a three-position segmented control — 1 · ½ · 0 — where
   each position is its own labelled submit button. The active one is filled, so
   the row's Parte reads at a glance without opening anything. */
.share-seg {
  display: inline-flex;
  flex: 0 0 auto;
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--ceniza);
}
.share-seg-btn {
  appearance: none;
  border: 0;
  border-left: 1px solid var(--ceniza-2);
  background: transparent;
  color: var(--humo-2);
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
  min-width: 34px;
  padding: 8px 6px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.share-seg-btn:first-child {
  border-left: 0;
}
.share-seg-btn:hover:not(:disabled) {
  background: var(--ceniza-2);
  color: var(--humo);
}
/* The active position is always the only filled cell, but ember is spent only
   where it says something. A whole Parte is what almost every row carries, so
   marking it ember paints the roster orange and leaves the two rows that
   actually alter the split — the media beca and the invitado — no louder than
   the five that do not. So: selected-and-ordinary reads as a raised cell,
   selected-and-exceptional burns. The control then agrees with the chip beside
   it instead of competing with it, and --brasa stays the one bold gesture. */
.share-seg-btn.is-on {
  /* Pressed in, not lit up: a cell darker than the track reads as selected on
     an ordinary row and on the ember-tinted `is-me` row alike, which a raised
     cell does not. */
  background: var(--carbon);
  color: var(--hueso);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, .45);
}
.share-seg-btn[value="0.5"].is-on,
.share-seg-btn[value="0"].is-on {
  background: var(--brasa);
  color: #fff;
  box-shadow: none;
}
.share-seg-btn:disabled {
  cursor: default;
  opacity: .75;
}
.share-seg-btn:focus-visible {
  outline: 2px solid var(--brasa);
  outline-offset: -2px;
}
/* Inline "1 · ½ · 0" cue in the admin hint above the grid. */
.share-legend {
  font-weight: 700;
  color: var(--humo);
  white-space: nowrap;
}
.participant-row .participant-actions {
  display: flex;
  gap: var(--s-1);
  flex: 0 0 auto;
}
/* the viewer's own row, ember-highlighted (#177) */
.participant-row.is-me {
  border-color: rgba(255, 90, 31, .5);
  background: rgba(255, 90, 31, .07);
}

/* ---------------------------------------------------------------------------
   The participant row on a phone (#192).

   At 412px the desktop row is one wrap-anything flex line, and the name is its
   only flexible item — so six action targets squeeze "Fernanda Rodriguez" down
   to "F", while shorter rows keep their name and wrap instead. Rows end up 64px
   or 130px tall with nothing deciding which, and the grid reads as noise.

   So on a phone the row stops being one line and becomes two deliberate zones:

        +------------------------------------------+
        | (S)  Soro                     (Media beca)|   identity
        | [  v  ] [  $  ] [  1  |  1/2  |  0  ] : [x]|   operations
        +------------------------------------------+

   The break is forced, not emergent: the action bar claims a full-width flex
   basis, so it always starts its own line and the identity line keeps the whole
   width for the name. Chips wrap under the name when they do not fit, which is
   the right thing to lose first.

   In the action bar the Parte takes the entire middle. It is the control this
   ticket is about and the one a thumb should find without aiming, so it is the
   widest element on the line rather than three 34px buttons wedged between two
   toggles. Removing a participant sits past a hairline, off the path of the
   controls people tap all evening, and in --clay rather than alarm red: warm,
   not alarm (see tokens), since the confirm dialog is what actually guards it.

   Note this deliberately overrides the "icon-only .btn-sm stays compact" carve
   out of #154 A6 above: compact is fine for an icon button that sits alone, but
   not for six of them shoulder to shoulder in one row.
   --------------------------------------------------------------------------- */
@media (max-width: 575.98px) {
  /* Rows must read as further apart than the two zones inside them. */
  .participant-list {
    gap: var(--s-3);
  }
  .participant-row {
    row-gap: var(--s-3);
    padding: var(--s-3);
  }
  /* A name may ellipse, but never down to an initial: it keeps a floor and the
     chips wrap below it instead. */
  .participant-row .participant-nm {
    min-width: 10ch;
  }

  /* Zone 2: a full-basis flex item always breaks onto its own line. */
  .participant-row .participant-actions {
    flex: 1 0 100%;
    gap: var(--s-2);
    align-items: stretch;
  }
  .participant-op {
    display: flex;
  }
  /* The two toggles: square, quiet, thumb-sized. */
  .op-attend .btn,
  .op-cashier .btn,
  .op-remove .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    font-size: 16px;
  }

  /* The Parte: the widest thing on the line. */
  .op-share {
    flex: 1 1 auto;
    min-width: 0;
  }
  .op-share .share-seg {
    display: flex;
    width: 100%;
  }
  .share-seg-btn {
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    padding: 0 var(--s-2);
    /* Chivo's tabular figures: 1 / 1/2 / 0 sit on one rhythm, so the control
       reads as a dial of the same quantity rather than three glyphs. */
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
  }

  /* Destructive, and separated by a hairline so it is not adjacent to the
     Parte. */
  .op-remove {
    margin-left: var(--s-1);
    padding-left: var(--s-2);
    border-left: 1px solid var(--ceniza-2);
  }
  .participant-row .op-remove .btn {
    color: var(--clay);
    border-color: rgba(214, 90, 63, .38);
    background: transparent;
  }
}

/* Bulk "add participants" picker (#177): filterable checkbox list — the group
   can be ~40 while an asado is 12–20, so a single-select won't do. */
.bulk-add {
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: var(--r-md);
  padding: var(--s-4);
}
.bulk-search {
  position: relative;
  margin-bottom: var(--s-3);
}
.bulk-search .bi {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--humo);
}
.bulk-search .form-control {
  padding-left: 36px;
}
.bulk-options {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  max-height: 320px;
  overflow-y: auto;
}
.bulk-opt {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  margin: 0;
}
.bulk-opt:hover {
  background: var(--ceniza-2);
}
.bulk-opt input[type="checkbox"] {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  accent-color: var(--brasa);
}
.bulk-av {
  width: 32px;
  height: 32px;
  border-radius: var(--r-full);
  background: var(--ember);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
  flex: 0 0 auto;
}
.bulk-nm {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--s-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bulk-tag {
  font-size: 10px;
  color: var(--humo);
  text-transform: uppercase;
  letter-spacing: .04em;
  border: 1px solid var(--ceniza-2);
  padding: 1px 6px;
  border-radius: var(--r-full);
}

/* danger zone */
.detail-danger {
  margin-top: var(--s-8);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  background: var(--clay-dim);
  border: 1px solid rgba(214, 90, 63, .3);
  border-radius: var(--r-md);
  padding: var(--s-4) var(--s-5);
}
.detail-danger .danger-txt .t {
  color: var(--clay);
  font-weight: 700;
  font-size: 15px;
}
.detail-danger .danger-txt .s {
  color: var(--humo-2);
  font-size: 13px;
  margin-top: 2px;
}
.detail-danger form {
  flex: 0 0 auto;
}
@media (max-width: 575.98px) {
  .detail-danger {
    flex-direction: column;
    align-items: flex-start;
  }
  .detail-header-main .detail-edit {
    align-self: flex-start;
  }
  /* Shrink the stat-card value type so a large amount ($91.600,00) fits the
     narrow tiles. */
  .stat-card .v,
  .you-amt {
    font-size: 18px;
    font-variant-numeric: tabular-nums;
  }

  /* #154 A6 — mobile tap targets: lift inputs, buttons and footer links to
     the ≥44px recommended touch area (auth forms were ~38px). Icon-only
     `.btn-sm` and `.btn-close` are intentionally left compact. */
  .form-control,
  .form-select {
    min-height: 44px;
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
  }
  .btn:not(.btn-sm):not(.btn-close) {
    min-height: 44px;
    padding-top: 0.6rem;
    padding-bottom: 0.6rem;
  }
  footer .small a {
    display: inline-block;
    padding: 0.35rem 0.15rem;
  }
}

/* ============================================================================
   Home landing (active-asado screen)

   Opens on the group's live asado. A focused single column that stays narrow
   on desktop, matching design-system/screens/home-active-event.html. Reuses
   the shared `.face` facepile treatment (see the asados list).
   ============================================================================ */
.home-wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: var(--s-4, 16px) var(--s-4, 16px) var(--s-6, 24px);
}

.home-eyebrow {
  font: var(--t-eyebrow);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--brasa);
  margin: 8px 0 10px;
}

/* Group context bar + switcher */
.home-groupbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.home-groupbar .home-eyebrow {
  margin: 0;
}
.home-groupbar__name {
  margin-left: auto;
  font: var(--t-meta);
  color: var(--humo-2);
}
.home-switcher {
  margin-left: auto;
}
.home-switcher__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  border-radius: 999px;
  padding: 7px 14px;
  color: var(--hueso);
  font: 600 14px/1 var(--font-ui);
}
.home-switcher__btn:hover {
  background: var(--ceniza-2);
}
.home-switcher__caret {
  font-size: 12px;
  color: var(--humo-2);
}

/* Hero card — the live asado */
.home-hero {
  display: block;
  text-decoration: none;
  color: var(--hueso);
  background: linear-gradient(180deg, rgba(255, 90, 31, .16), var(--ceniza) 55%);
  border-radius: 20px;
  padding: 20px;
  position: relative;
  overflow: hidden;
}
.home-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 20px;
  padding: 1px;
  background: var(--ember);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
}
/* Settled asado (read-only): drop the ember glow for a calmer, muted card. */
.home-hero--closed {
  background: var(--ceniza);
}
.home-hero--closed::before {
  background: var(--ceniza-2);
}
.home-hero:hover {
  color: var(--hueso);
}
.home-hero__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}
.home-hero__flame {
  font-size: 24px;
  color: var(--brasa);
  line-height: 1;
}
.home-hero__tag {
  font: 700 11px/1 var(--font-ui);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: #1a1412;
  background: var(--brasa);
  padding: 6px 11px;
  border-radius: 999px;
}
.home-hero__tag--closed {
  color: var(--humo-2);
  background: var(--ceniza-2);
}
/* Planned asado (not started yet): calm card + outline tag, mirroring the
   detail-status--planned chip. Signals "upcoming" without the live ember glow. */
.home-hero--planned {
  background: var(--ceniza);
}
.home-hero--planned::before {
  background: var(--ceniza-2);
}
.home-hero--planned .home-hero__flame {
  color: var(--humo-2);
}
.home-hero__tag--planned {
  color: var(--hueso);
  background: transparent;
  border: 1px solid var(--ceniza-2);
}
.home-planned-hint {
  margin-top: var(--s-4);
  text-align: center;
  font-size: 14px;
}
.home-hero__title {
  font: 700 26px/1.1 var(--font-ui);
  margin: 10px 0 0;
}
.home-hero__date {
  color: var(--hueso);
  opacity: .85;
  font-size: 14px;
  margin-top: 3px;
}
/* ------------------------------------------------------------------
   Focused-card footer + the feed of previous asados (#195).

   The card footer carries the viewer's own standing on the left and an
   explicit way in on the right — people were not realising the card was
   tappable. Below it the feed lists every previous asado as one line:
   an attendance dot, the number, date · location, a chevron. A missed
   asado gets a hollow dot and a muted row, and that muting is the only
   explanation there is — no legend, no heading, by design.
   ------------------------------------------------------------------ */

.home-hero__foot {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, .08);
}
.home-hero__yours {
  font-size: 14px;
  color: var(--humo-2);
  min-width: 0;
}
.home-hero__yours b {
  font-weight: 700;
  color: var(--chimi);           /* creditor — "te deben" */
}
.home-hero__yours--debtor b {
  color: var(--clay);            /* debtor — "debés" */
}
.home-hero__yours--even {
  color: var(--humo-2);          /* settled — no amount, no colour */
}
.home-hero__enter {
  margin-left: auto;             /* stays right even when there is no balance */
  color: var(--brasa);
  font: 700 14px/1 var(--font-ui);
  white-space: nowrap;
}

/* One asado per line. */
.feed {
  margin-top: 20px;
}
.feed-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 15px 2px;
  border-bottom: 1px solid var(--ceniza);
  text-decoration: none;
  color: inherit;
}
.feed-row:hover {
  color: inherit;
}
.feed-row__mid {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.feed-row__t {
  font: 700 16px/1.15 var(--font-display);
  letter-spacing: -.01em;
}
.feed-row__s {
  font-size: 13px;
  color: var(--humo-2);
}
.feed-row__chev {
  margin-left: auto;
  color: var(--humo);
  font-size: 15px;
  line-height: 1;
  flex: 0 0 auto;
}

/* Filled ember = you were there. Hollow ring + muted row = you were not. */
.feed-row__mark {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--brasa);
  box-shadow: 0 0 0 3px rgba(255, 90, 31, .13);
}
.feed-row__mark--absent {
  background: transparent;
  border: 1.5px solid var(--humo);
  box-shadow: none;
}
.feed-row--absent .feed-row__t {
  color: var(--humo);
}
.feed-row--absent .feed-row__s {
  color: var(--humo);
  opacity: .85;
}

/* htmx reveal sentinel: visible while the next page is on its way. */
.feed-more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 22px 0 6px;
  color: var(--humo);
  font-size: 13px;
}
.feed-more[data-failed] {
  cursor: pointer;
}
/* Normal state shows the spinner + "cargando"; a failed fetch shows the retry. */
.feed-more__retry,
.feed-more[data-failed] .feed-more__spin,
.feed-more[data-failed] .feed-more__loading {
  display: none;
}
.feed-more[data-failed] .feed-more__retry {
  display: inline;
  color: var(--brasa);
}
.feed-more__spin {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  flex: 0 0 auto;
  border: 2px solid var(--ceniza-2);
  border-top-color: var(--humo-2);
  animation: feed-spin 1s linear infinite;
}
@keyframes feed-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .feed-more__spin {
    animation: none;
  }
}

.home-nextcta {
  margin-top: 16px;
}

/* Empty states (no groups / no events) */
.home-empty {
  text-align: center;
  padding: var(--s-8, 40px) var(--s-4, 16px);
}
.home-empty__icon {
  font-size: 48px;
  color: var(--humo);   /* muted empty-state icon, consistent with the rest (#153 F7) */
  line-height: 1;
  margin-bottom: 12px;
}
.home-empty__title {
  font: 700 22px/1.2 var(--font-ui);
  margin-bottom: 8px;
}
.home-empty__lead {
  color: var(--humo-2);
  max-width: 40ch;
  margin: 0 auto 20px;
}
.home-empty__link {
  color: var(--brasa);
  text-decoration: none;
  font-weight: 600;
}

@media (min-width: 992px) {
  .home-wrap {
    padding: 28px 20px 40px;
  }
  .home-hero__title {
    font-size: 30px;
  }
}

/* Print: hide chrome. */
@media print {
  .navbar,
  .app-navbar,
  .app-ctxbar,
  .app-bottomnav,
  .app-bottomnav-spacer,
  .app-toasts,
  .app-toast,
  .btn,
  footer {
    display: none;
  }
  .container {
    max-width: 100%;
  }
}

/* Profile screen: the account photo, above the name fields. */
.profile-photo {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--ceniza-2);
}
.profile-photo-placeholder {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: var(--ceniza);
  border: 1px solid var(--ceniza-2);
  color: var(--hueso);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
}
