/* Mi Puente — design system.
 * Tokens are Jimbo's, from the Figma file delivered 2026-08-31: the colour ramps,
 * the type scale (IBM Plex Sans for titles, Mulish for body), the 8px spacing
 * scale, and the single soft elevation. Names match the Figma variable names so a
 * value can be traced back to the source without guessing.
 *
 * Warm, human, high-contrast, big-button. Mobile-first; a phone frame appears on
 * larger screens so it demos well on a laptop. */

:root {
  /* ---- ramps, straight from the Figma variables -------------------------- */
  /* orange: the primary action colour */
  --orange-900: #351803; --orange-800: #612B05; --orange-700: #9B4508;
  --orange-600: #C1570B; --orange-500: #EC6A0D; --orange-400: #F48739;
  --orange-300: #F7A469; --orange-200: #F9C199; --orange-100: #FCDCC5;
  --orange-50:  #FEF0E7;
  /* aqua: the live/positive colour (recording, confirmed, on) */
  --aqua-900: #053D31; --aqua-800: #085443; --aqua-700: #0C7E65;
  --aqua-600: #0E9577; --aqua-500: #11B591; --aqua-400: #15DBAF;
  --aqua-300: #3BEDC6; --aqua-200: #7CF3D9; --aqua-100: #B4F8E9;
  --aqua-50:  #E3FCF7;
  /* neutral: warm greys, not clinical */
  --neutral-900: #1F1E1B; --neutral-800: #43423D; --neutral-700: #52504C;
  --neutral-600: #6F6D68; --neutral-500: #8C8A84; --neutral-400: #A3A19A;
  --neutral-300: #C8C6BE;
  --green-800: #004018; --green-700: #006228; --green-600: #008339;
  --green-500: #3AA157; --green-400: #6BB47A; --green-300: #A3D4AC;
  --green-200: #C8E6CC; --green-100: #E3F1E5; --green-50: #F2F9F3;
  --amber-900: #2B1A00; --amber-800: #472F00; --amber-700: #6C4900;
  --amber-600: #916300; --amber-500: #B67E00; --amber-400: #C59850;
  --amber-300: #E0C192; --amber-200: #EDD9BD; --amber-100: #F5EBDD;
  --amber-50:  #FBF6EF;
  --red-900: #400106; --red-800: #68000C; --red-700: #9A0218;
  --red-600: #C12C32; --red-500: #DB5A57; --red-400: #E58079;
  --red-300: #F9B1AB; --red-200: #FDD0CC; --red-100: #FEE7E4;
  --red-50:  #FFF4F3;
  --beige-400: #F0E8DE;              /* Secondary Beige 400, the warm ground */

  /* Case status, straight from the Figma variables. Three tones plus a neutral:
   * waiting (something is happening, nothing is owed by you), committed (a human
   * has it), urgent (needs a decision), and paused (you stopped it yourself). */
  --status-waiting-bg: #FEF6E7;    --status-waiting: #895B06;
  --status-committed-bg: #F2F9F3;  --status-committed: #006228;
  --status-urgent-bg: #FFF4F3;     --status-urgent: #9A0218;
  --status-idle-bg: #F4F1EB;       --status-idle: #5D5A56;

  /* ---- roles: what the ramps are used FOR -------------------------------
   * These names are Figma's, not ours. The design file publishes its semantic
   * layer as CSS custom properties already, so we use them verbatim and the next
   * import diffs cleanly instead of needing a translation in somebody's head.
   * Values reconciled to the Figma variables on 2026-09-09; the previous values
   * are in the session log if any of them turn out to look wrong on a phone. */
  --color-surface-base: #f9f7f0;     /* the app ground */
  --color-surface-raised: #ffffff;   /* a card sitting on it */
  --color-surface-sunken: #a3a19a;   /* a track behind a filled indicator */
  --color-text-primary: #292824;
  --color-text-secondary: #5d5a56;
  --color-text-muted: #8c8a84;
  --color-text-on-brand: #ffffff;
  --color-border-subtle: #dfdcd4;    /* card edges and the 1px rules inside them */
  --danger: var(--red-700);
  --ok: var(--aqua-700);

  /* Brand. Orange carries the primary action; aqua carries "live" and "yes".
   * Still overwritable at runtime by applyTheme() so the demo can be reskinned. */
  --color-brand-fill: var(--orange-500);
  --color-brand-text: var(--orange-600);
  --color-brand-border: var(--orange-500);
  --color-brand-subtle: var(--orange-50);
  --accent: var(--aqua-500);
  --seal: var(--orange-500);

  /* ---- type ------------------------------------------------------------- */
  --font-title: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-body: "Mulish", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --title-lg: 26px; --title-lg-lh: 36px;
  --title-md: 20px; --title-md-lh: 28px;
  --title-sm: 16px; --title-sm-lh: 24px;
  --title-xs: 14px; --title-xs-lh: 20px;
  --body-lg: 16px;  --body-lg-lh: 26px;
  --body-md: 14px;  --body-md-lh: 20px;
  --body-sm: 12px;  --body-sm-lh: 18px;

  /* ---- space: 8px grid, 4px where it needs to be finer ------------------ */
  --space-4: 4px;   --space-8: 8px;   --space-12: 12px; --space-16: 16px;
  --space-20: 20px; --space-24: 24px; --space-32: 32px; --space-40: 40px;
  --space-48: 48px; --space-56: 56px; --space-64: 64px;

  /* ---- elevation: one soft shadow, used sparingly ----------------------- */
  --shadow: 0 1px 2px rgba(41, 40, 36, .04), 0 4px 16px rgba(41, 40, 36, .06);

  /* scale (the accessibility text-size control multiplies this) */
  --scale: 1;
  --r: 16px;         /* card radius */
  --tap: 64px;       /* minimum tap target */
  --pad: var(--space-20);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font-body);
  background: #2a2622;                 /* backdrop behind the phone frame */
  color: var(--color-text-primary);
  font-size: calc(var(--body-lg) * var(--scale));
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* ------------------------------------------------------------- phone frame -- */
#app {
  position: relative;
  width: 100%;
  max-width: 430px;
  height: 100vh;
  height: 100dvh;
  margin: 0 auto;
  background:
    linear-gradient(180deg,
      #FCE7D2 0%,
      #FDF4EA 26%,
      var(--color-surface-base) 52%,
      #F3F7F2 88%,
      #EAF3EE 100%);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
@media (min-width: 480px) {
  body { padding: 24px 0; }
  #app {
    min-height: min(880px, calc(100vh - 48px));
    height: min(880px, calc(100vh - 48px));
    border-radius: 40px;
    box-shadow: 0 30px 80px rgba(0,0,0,.45), 0 0 0 12px #14110e, 0 0 0 13px #3a352f;
  }
}

/* ----------------------------------------------------------------- header -- */
/* App bar. Transparent, dark text, sitting on the page's own gradient rather than
 * on a coloured slab (the design system, 2026-08-31). The slab read as heavier
 * than this app should feel, and it fought the warm ground the palette is built
 * on. Back on the left, title, an optional close on the right. */
.appbar {
  background: transparent;
  color: var(--color-text-primary);
  padding: var(--space-12) var(--space-16);
  display: flex;
  align-items: center;
  gap: var(--space-12);
  flex: 0 0 auto;
}
.appbar .seal { width: 36px; height: 36px; flex: 0 0 auto; color: var(--color-brand-fill); }
.appbar .titles { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.appbar .sponsor {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-sm) * var(--scale));
}
.appbar .sub { font-size: calc(var(--body-sm) * var(--scale)); color: var(--color-text-muted); }
.appbar .powered { margin-left: auto; font-size: calc(10px * var(--scale)); color: var(--color-text-muted); white-space: nowrap; }
.appbar.back-row { cursor: default; }
.appbar .backbtn {
  background: transparent; color: var(--color-text-primary);
  border: none; border-radius: 999px; height: 40px; min-width: 40px; padding: 0 var(--space-8) 0 0;
  font-size: calc(var(--body-md) * var(--scale)); font-weight: 600;
  display: inline-flex; align-items: center; gap: var(--space-4);
  cursor: pointer;
}
.appbar .backbtn:active { transform: scale(.96); }

/* ---------------------------------------------------------------- content -- */
.screen {
  flex: 1 1 auto;
  background: transparent;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--pad);
  padding-bottom: 28px;
  animation: fade .28s ease;
}
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

h1, h2, h3, .appbar .sponsor, .btn, .tile .lbl, .choice .txt .t {
  font-family: var(--font-title);
}
h1 {
  font-family: var(--font-title);
  font-size: calc(var(--title-lg) * var(--scale));
  line-height: calc(var(--title-lg-lh) / var(--title-lg));
  margin: var(--space-8) 0 var(--space-12); font-weight: 700; letter-spacing: 0;
}
h2 {
  font-size: calc(var(--title-md) * var(--scale));
  line-height: calc(var(--title-md-lh) / var(--title-md));
  margin: var(--space-24) 0 var(--space-12); font-weight: 600;
}
p  { margin: 0 0 14px; color: var(--color-text-secondary); }
.lead { font-size: calc(var(--body-lg) * var(--scale)); line-height: calc(var(--body-lg-lh) / var(--body-lg)); color: var(--color-text-primary); }
.muted { color: var(--color-text-muted); }
.small { font-size: calc(var(--body-sm) * var(--scale)); line-height: calc(var(--body-sm-lh) / var(--body-sm)); }
.center { text-align: center; }

/* ---------------------------------------------------------------- buttons -- */
.btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: var(--tap);
  padding: 16px 20px; border: none; border-radius: var(--r);
  font-size: calc(var(--body-lg) * var(--scale)); font-weight: 700;
  font-family: var(--font-body); letter-spacing: 1px;
  cursor: pointer; text-align: center; text-decoration: none;
  transition: transform .06s ease, box-shadow .2s ease, background .2s ease;
}
.btn:active { transform: scale(.98); }
.btn-primary { background: var(--color-brand-fill); color: var(--color-text-on-brand); box-shadow: 0 6px 18px rgba(11,107,58,.28); }
.btn-primary:active { box-shadow: 0 2px 8px rgba(11,107,58,.28); }
.btn-ghost { background: transparent; color: var(--color-brand-fill); font-weight: 700; }
.btn-outline { background: var(--color-surface-raised); color: var(--color-text-primary); border: 1.5px solid var(--color-border-subtle); }
/* The brand outline: an alternative to the primary action, not a lesser one.
 * Grey-on-white read as disabled next to a filled orange button. */
.btn-outline.brand { background: transparent; color: var(--color-brand-fill); border: 1px solid var(--color-brand-fill); box-shadow: none; }
.btn-ghost.brandtext { color: var(--color-brand-fill); }
.btn-block + .btn-block { margin-top: 12px; }
.btn.sm { min-height: 46px; padding: 10px 16px; font-size: calc(15px * var(--scale)); width: auto; border-radius: 999px; }
.actions-bottom { margin-top: 24px; }

/* ---------------------------------------------------------------- big tiles -- */
/* The home hub and the "how to tell it" chooser: large, plain, unmissable. */
.hero {
  display: block; width: 100%; text-align: left;
  background: var(--color-brand-fill); color: var(--color-text-on-brand);
  border: none; border-radius: 24px; padding: 24px; cursor: pointer;
  box-shadow: 0 10px 28px rgba(11,107,58,.30);
  transition: transform .08s ease;
}
.hero:active { transform: scale(.99); }
.hero .mic { font-size: 34px; margin-bottom: 8px; display: block; }
.hero h2 { color: var(--color-text-on-brand); margin: 4px 0 4px; font-size: calc(23px * var(--scale)); }
.hero p { color: var(--color-text-on-brand); opacity: .9; margin: 0; }

.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 14px; }
.tile {
  background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: 20px;
  padding: 18px 16px; min-height: 108px; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; gap: 6px; font-family: inherit;
  transition: transform .08s ease, border-color .2s ease;
}
.tile:active { transform: scale(.98); }
.tile .ic { font-size: 26px; }
.tile .lbl { font-weight: 700; font-size: calc(16px * var(--scale)); color: var(--color-text-primary); }
.tile.span2 { grid-column: 1 / -1; min-height: 0; flex-direction: row; align-items: center; }
.tile.span2 .lbl { flex: 1; }

.choice {
  display: flex; align-items: center; gap: 16px; width: 100%; text-align: left;
  background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: 20px;
  padding: 20px; margin-bottom: 12px; cursor: pointer; font-family: inherit;
  transition: transform .08s ease, border-color .2s;
}
.choice:active { transform: scale(.99); }
/* .choice is also used on <a href="tel:..."> in the information sections. */
a.choice { text-decoration: none; color: var(--color-text-primary); }
.choice.primary { border-color: var(--color-brand-fill); border-width: 2px; }
.choice .ic { font-size: 30px; width: 44px; text-align: center; flex: 0 0 auto; }
.choice .txt { flex: 1; }
.choice .txt .t { display: block; font-weight: 700; font-size: calc(18px * var(--scale)); }
.choice .txt .s { display: block; margin-top: 2px; color: var(--color-text-muted); font-size: calc(14px * var(--scale)); line-height: 1.35; }
.choice .chev { color: var(--color-text-muted); font-size: 22px; }

/* ------------------------------------------------------------------ cards -- */
.card { background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: var(--r); padding: 18px; margin-bottom: 14px;   box-shadow: var(--shadow);
}
.card h3 { margin: 0 0 8px; font-size: calc(16px * var(--scale)); }
.note {
  background: #fff8ea; border: 1px solid #f0e2c4; color: #6b5720;
  border-radius: 14px; padding: 12px 14px; font-size: calc(13.5px * var(--scale)); margin: 8px 0 16px;
}
.callout { background: rgba(11,107,58,.07); border-radius: 14px; padding: 14px 16px; margin: 14px 0; }

/* chips / tags */
.chip { display: inline-flex; align-items: center; gap: 6px; background: #eef3ee; color: var(--color-brand-text);
  border-radius: 999px; padding: 5px 12px; font-size: calc(12.5px * var(--scale)); font-weight: 600; margin: 4px 6px 0 0; }
.chip.doc { background: #f1eee9; color: var(--color-text-secondary); }
.chip.close { cursor: pointer; }
.chip .x { opacity: .55; font-weight: 800; }

.tag { display: inline-block; background: var(--color-brand-fill); color: var(--color-text-on-brand); border-radius: 6px;
  padding: 2px 8px; font-size: calc(11.5px * var(--scale)); font-weight: 700; vertical-align: middle; }
.tag.alt { background: var(--accent); }
.tag.soft { background: #eef3ee; color: var(--color-brand-text); }

/* bulleted, human list */
ul.plain { list-style: none; padding: 0; margin: 0 0 8px; }
ul.plain li { position: relative; padding: 8px 0 8px 28px; border-bottom: 1px solid var(--color-border-subtle); }
ul.plain li:last-child { border-bottom: none; }
ul.plain li::before { content: ""; position: absolute; left: 6px; top: 16px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--color-brand-fill); }
ul.check li::before { content: "✓"; background: none; color: var(--color-brand-fill); font-weight: 800; left: 2px; top: 6px; width: auto; height: auto; }

/* ---------------------------------------------------------------- avatars -- */
.avatar { width: 56px; height: 56px; border-radius: 50%; background: var(--color-brand-fill); color: var(--color-text-on-brand);
  display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 20px; flex: 0 0 auto; }
.avatar.lg { width: 72px; height: 72px; font-size: 26px; }

/* ------------------------------------------------------------- record view -- */
.rec-wrap { text-align: center; padding: 28px 0; }
.rec-btn {
  width: 120px; height: 120px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--color-brand-fill); color: var(--color-text-on-brand); display: grid; place-items: center;
  margin: 0 auto; transition: transform .1s ease;
}
.rec-btn:active { transform: scale(.96); }
.rec-btn.live { background: var(--color-brand-fill); animation: pulse 1.8s infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(236,106,13,.38);} 70% { box-shadow: 0 0 0 22px rgba(236,106,13,0);} 100% { box-shadow: 0 0 0 0 rgba(236,106,13,0);} }
.timer { font-variant-numeric: tabular-nums; font-size: calc(22px * var(--scale)); font-weight: 700; margin: 4px 0; }
.wave { display: flex; align-items: center; justify-content: center; gap: 4px; height: 44px; margin: 10px 0 6px; }
.wave span { width: 4px; background: var(--aqua-600); border-radius: 2px; height: 12px; animation: bar 1s ease-in-out infinite; }
.wave.paused span { animation-play-state: paused; opacity: .35; }
@keyframes bar { 0%,100%{ height: 10px;} 50%{ height: 34px;} }

/* ------------------------------------------------------------- case rows -- */
.case {
  background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: var(--r);
  padding: 18px; margin-bottom: 14px;
}
.case .top { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.case .top .name { font-weight: 800; font-size: calc(18px * var(--scale)); flex: 1; }
.case .meta { color: var(--color-text-muted); font-size: calc(13px * var(--scale)); margin-bottom: 10px; }
.status { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: calc(14px * var(--scale)); }
.dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.dot.searching { background: #d9a521; }
.dot.review { background: #d9a521; }
.dot.engaged { background: var(--ok); }
.dot.sent { background: #7a95c9; }
.dot.paused { background: #b0a99e; }
.case-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--color-border-subtle); }
.next { background: var(--color-surface-base); border-radius: 12px; padding: 12px 14px; margin-top: 12px; font-size: calc(14.5px * var(--scale)); color: var(--color-text-secondary); }
.next b { color: var(--color-text-primary); }
.attorney-row { display: flex; align-items: center; gap: 14px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--color-border-subtle); }
.attorney-row .who { line-height: 1.25; }
.attorney-row .who .n { font-weight: 700; }

.ledger-row { display: flex; align-items: center; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--color-border-subtle); }
.ledger-row:last-child { border-bottom: none; }
.ledger-row .who { flex: 1; }
.ledger-row .who .n { font-weight: 700; }

/* ------------------------------------------------------- emergency affordance -- */
/* Persistent, always reachable from the hub. Present but honest in the demo. */
.emergency-bar {
  flex: 0 0 auto; margin: 0; padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
  background: #fbeced; border-top: 1px solid #f0cdd0;
}
.emergency-bar button {
  width: 100%; min-height: 54px; border: 2px solid var(--danger); background: #fff; color: var(--danger);
  border-radius: 14px; font-weight: 800; font-size: calc(16px * var(--scale)); cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 10px; font-family: inherit;
}
.emergency-bar button:active { background: var(--danger); color: #fff; }

/* --------------------------------------------------------------- form bits -- */
input[type="text"], input[type="tel"], textarea {
  width: 100%; font-family: inherit; font-size: calc(17px * var(--scale)); color: var(--color-text-primary);
  background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: 14px; padding: 14px 16px;
}
textarea { min-height: 140px; resize: vertical; line-height: 1.5; }
input:focus, textarea:focus { outline: none; border-color: var(--color-brand-fill); }

.toggle-row { display: flex; align-items: flex-start; gap: 14px; padding: 16px 0; border-bottom: 1px solid var(--color-border-subtle); cursor: pointer; }
.toggle-row:last-of-type { border-bottom: none; }
.toggle-row .lbl { flex: 1; }
.toggle-row .lbl .s { color: var(--color-text-muted); font-size: calc(13.5px * var(--scale)); }
.switch { width: 52px; height: 32px; border-radius: 999px; background: #d6cfc4; flex: 0 0 auto; position: relative; transition: background .2s; margin-top: 2px; }
.switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%; background: #fff; transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.2); }
/* Aqua, not orange: in this system orange is the action colour and aqua means
 * on / yes / live, which is what a switch in its on position is saying. */
.switch.on { background: var(--aqua-500); }
.switch.on::after { transform: translateX(20px); }

.seg { display: flex; gap: 8px; background: #efeae2; padding: 5px; border-radius: 14px; }
.seg button { flex: 1; border: none; background: transparent; padding: 12px; border-radius: 10px; font-family: inherit;
  font-size: calc(15px * var(--scale)); font-weight: 700; color: var(--color-text-secondary); cursor: pointer; }
.seg button.on { background: var(--color-surface-raised); color: var(--color-text-primary); box-shadow: 0 1px 4px rgba(0,0,0,.1); }

/* Tabs, from the design system's Tab component (Figma 200:5326). Three of them
 * sit under the app bar on Ayudame and stay there in every state, so "habla por
 * mi" is one tap away instead of a scroll past the recording card. The designer's
 * note on the board gives the reason: tabs group related content rather than
 * stacking it all on one screen until it is saturated and hard to read.
 * Measurements are his: 64px tall, 24px icon over a 14/20 label, a 3px indicator
 * inset 2px with the top corners rounded, on a 1px bottom rule. */
.dstabs {
  display: flex; gap: var(--space-8); align-items: center;
  padding: 0 var(--space-8); margin: 0 calc(var(--pad) * -1) var(--space-16);
  border-bottom: 1px solid var(--color-border-subtle);
}
.dstabs button {
  flex: 1 0 0; min-width: 0; position: relative; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; height: 64px; min-height: 48px; padding: 10px var(--space-16) 8px;
  border: none; background: transparent; cursor: pointer;
  font-family: var(--font-body); font-size: calc(var(--body-md) * var(--scale));
  line-height: var(--body-md-lh); font-weight: 600; color: var(--color-text-secondary);
}
.dstabs button .ic { display: flex; width: 24px; height: 24px; }
.dstabs button.on { font-weight: 700; color: var(--color-brand-text); }
/* The indicator is the tab's own child so it tracks the tab's width. */
.dstabs button.on::after {
  content: ""; position: absolute; bottom: 0; left: 2px; right: 2px; height: 3px;
  background: var(--color-brand-fill);
  border-radius: 100px 100px 0 0;
}
.dstabs button:focus-visible { outline: 2px solid var(--color-brand-fill); outline-offset: -2px; }

/* The ask beside the face on a person's page. Same shape as the one on Home so
 * the two read as one control in two places, not two controls. */
.person-hd.withask { position: relative; }
.askbeside {
  display: inline-flex; flex-direction: column; align-items: center; gap: 2px;
  margin-top: var(--space-12); padding: var(--space-8) var(--space-16);
  border: none; background: transparent; cursor: pointer; font-family: inherit;
  color: var(--color-brand-text);
}
.askbeside .ic {
  display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--color-brand-fill); color: var(--color-text-on-brand);
}
.askbeside .lb { font-weight: 700; font-size: calc(13px * var(--scale)); line-height: 18px; }
.askbeside:active .ic { background: var(--color-brand-text); }
.askbeside.off { cursor: default; color: var(--color-text-muted); }
.askbeside.off .ic { background: var(--color-surface-sunken); color: var(--color-text-on-brand); }

/* What has actually happened with this person. */
.acts { padding: 0 var(--space-16); }
.act-row {
  display: flex; gap: var(--space-12); align-items: flex-start;
  padding: var(--space-16) 0; border-bottom: 1px solid var(--color-border-subtle);
}
.act-row:last-child { border-bottom: none; }
.act-row > .ic { flex: 0 0 auto; display: flex; width: 24px; color: var(--color-text-muted); }
.act-row.ok > .ic { color: var(--ok); }
.act-row.alarm > .ic { color: var(--danger); }
.act-row.alarm b { color: var(--danger); }

/* The count beside a group heading on Mi gente. */
h2.sec .cnt {
  display: inline-block; min-width: 22px; padding: 0 6px; margin-left: 6px;
  border-radius: 999px; background: var(--color-brand-subtle);
  color: var(--color-brand-text); text-align: center;
  font-size: calc(13px * var(--scale)); line-height: 22px; font-weight: 700;
}

/* The four plan sections as numbered steps (2026-09-21). A greyed tick read as
 * "done, but dimmed" rather than "still to do", which is the opposite of what it
 * meant. A number says step three of four and carries no such ambiguity; it
 * becomes a tick only once she has actually marked it done. */
.choice .halo { position: relative; }
.planrow { position: relative; padding-left: 56px; }
.stepnum {
  position: absolute; left: var(--space-16); top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-title); font-weight: 700;
  font-size: calc(var(--body-md) * var(--scale));
  border: 2px solid var(--color-border-subtle);
  background: var(--color-surface-raised); color: var(--color-text-secondary);
}
/* Not started: outlined, so it reads as an empty slot waiting to be filled. */
.planrow.is-todo .stepnum { border-color: var(--color-brand-fill); color: var(--color-brand-text); }
/* Answered but not confirmed: filled, because there is something in it. */
.planrow.is-ready .stepnum {
  background: var(--color-brand-fill); border-color: var(--color-brand-fill);
  color: var(--color-text-on-brand);
}
/* Done: a tick, and only then. */
.planrow.is-done .stepnum {
  background: var(--ok); border-color: var(--ok); color: var(--color-text-on-brand);
}

/* The lawyers question, where Mis casos sits once there are cases. It is the
 * stage 1 exit metric, so it has to be answerable in one tap and it must never
 * imply somebody is coming. */
.card.vote { text-align: left; margin: 0 var(--pad); }
.card.vote .cs-t { font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-sm) * var(--scale)); line-height: var(--title-sm-lh); }
.card.vote.done { display: flex; align-items: flex-start; gap: var(--space-12); }

/* Walk with me. Duration as chips rather than a picker: the number does not
 * need to be exact and a picker is the wrong control one-handed. */
.armchips { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-12); margin: var(--space-20) 0; }
.armchip {
  padding: var(--space-20); border-radius: var(--r); cursor: pointer; font-family: inherit;
  border: 1px solid var(--color-border-subtle); background: var(--color-surface-raised);
  font-size: calc(var(--body-lg) * var(--scale)); font-weight: 700; color: var(--color-text-primary);
}
.armchip:active { border-color: var(--color-brand-fill); background: var(--color-brand-subtle); }

.choice.walkcta { margin-top: var(--space-16); }

/* The open window. A countdown and what she can do to it, and nothing that
 * names anybody, because the phone may not be in her hands. */
.card.armed { text-align: left; margin-top: var(--space-16); border-color: var(--color-brand-fill); }
.card.armed.warn { border-color: var(--danger); }
.card.armed .armtop { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-8); margin-bottom: var(--space-12); }
.card.armed .al { font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-sm) * var(--scale)); }
.card.armed .left { color: var(--color-text-secondary); font-size: calc(var(--body-md) * var(--scale)); }
.card.armed.warn .left b { color: var(--danger); }
.card.armed .warnhead { margin-bottom: var(--space-12); color: var(--danger); }
.card.armed .warnhead .muted { color: var(--color-text-secondary); }
.hold-btn.armout { min-height: 52px; border-radius: 14px; margin-top: var(--space-12);
  font-size: calc(var(--body-md) * var(--scale)); }
.hold-btn.armout .hold-label { height: 52px; }
/* Safe is green wherever it appears. It is the one action that ends an episode
   for everybody, so it is held rather than tapped, and it is never red. */
.hold-btn.safe {
  background: var(--status-committed); border-color: var(--status-committed);
  color: var(--color-text-on-brand);
}
.hold-btn.safe.holding { box-shadow: 0 0 0 4px rgba(0,98,40,.25); }
.card.armed .hold-btn:not(.safe) { margin-top: 0; }
.card.armed ul.plain { margin: 0 0 var(--space-16); }
.btn.free { border-style: dashed; }

/* Pinned above the tabs while a window is open, so she cannot forget it. */
.band-armed {
  display: flex; align-items: center; gap: var(--space-8); width: 100%;
  padding: var(--space-12) var(--pad); border: none; cursor: pointer;
  background: var(--color-brand-fill); color: var(--color-text-on-brand);
  font-family: inherit; font-weight: 700; font-size: calc(var(--body-md) * var(--scale));
}
.band-armed.warn { background: var(--danger); }
.band-armed .pl { display: flex; align-items: center; gap: var(--space-8); flex: 1; }
.band-armed .lf { font-variant-numeric: tabular-nums; }

/* The rights card is its poster. Title over the image under a scrim, rather
 * than a picture boxed inside a card that was itself boxed. */
.card-slide.right.poster {
  position: relative; padding: 0; overflow: hidden; min-height: 200px;
  background-size: cover; background-position: center; border: none;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.card-slide.right.poster .rt-foot {
  /* margin-top:auto rather than justify-content, which the base .card-slide
     rules were overriding. */
  margin-top: auto;
  position: relative; z-index: 1; padding: var(--space-16);
  background: linear-gradient(180deg, rgba(23,22,20,0) 0%, rgba(23,22,20,.86) 55%);
  color: #fff;
}
.card-slide.right.poster .rt-foot .cs-t { color: #fff; }
.card-slide.right.poster .rt-foot .cs-b { color: rgba(255,255,255,.82); }
.card-slide.right.poster .playbig {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -60%); z-index: 1;
}

/* "Need a lawyer?" as a standing affordance rather than a block on Home. */
/* Centred in whatever space is left between the last carousel and the tabs. */
.screen.hubcol { display: flex; flex-direction: column; }
.votewrap { flex: 1 0 auto; display: flex; align-items: center; justify-content: center;
  min-height: 120px; padding: var(--space-24) var(--pad); }
.votechip {
  display: flex; align-items: center; gap: var(--space-8);
  padding: var(--space-8) var(--space-16); border-radius: 999px; cursor: pointer;
  border: 1px solid var(--color-border-subtle); background: var(--color-surface-raised);
  color: var(--color-brand-text); font-family: inherit; font-weight: 700;
  font-size: calc(var(--body-md) * var(--scale));
}
.votechip .ic { display: flex; }
.votechip:active { background: var(--color-brand-subtle); }

.field-label { font-weight: 700; margin: 18px 0 8px; }

/* The Avisa sheet, from the design system's Bottom Sheet (Figma 261:10058).
 * It replaces four full-screen steps with one tap and one sheet: pick what is
 * happening, confirm who hears it, send. His geometry: a 28px top radius, a
 * 32x4 drag handle, a 20/28 title, rows at 12px padding inside a 16px radius,
 * and a 76px-radius primary button. */
.avisa-sheet-wrap {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: flex-end;
  justify-content: center; background: rgba(41, 40, 36, .45);
  animation: fade .18s ease;
}
/* max-width matches the app shell: the wrap is fixed to the viewport, so without
 * it the sheet escapes the phone frame on a desktop screen. */
.avisa-sheet {
  position: relative; width: 100%; max-width: 420px; box-sizing: border-box;
  max-height: 88%; overflow-y: auto; animation: sheet-up .22s ease;
  background: var(--color-surface-raised);
  border-radius: 28px 28px 0 0; padding: 0 var(--space-16) var(--space-20);
  display: flex; flex-direction: column; gap: var(--space-8);
}
.avisa-sheet .grab { align-self: center; width: 32px; height: 4px; border-radius: 100px;
  background: var(--color-surface-sunken); margin: var(--space-16) 0; flex: 0 0 auto; }
.avisa-sheet .x {
  position: absolute; top: 44px; right: var(--space-16); width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--color-text-secondary); cursor: pointer;
}
.avisa-sheet h2 {
  font-family: var(--font-title); font-weight: 600; text-align: center;
  font-size: calc(var(--title-md) * var(--scale)); line-height: var(--title-md-lh);
  color: var(--color-text-primary); margin: 0 0 var(--space-20);
}
.avisa-sheet .who-q {
  font-family: var(--font-title); font-weight: 600; text-align: center;
  font-size: calc(var(--title-sm) * var(--scale)); line-height: var(--title-sm-lh);
  letter-spacing: .16px; color: var(--color-text-primary); margin-bottom: 13px;
}
.avisa-sheet .who-row {
  display: flex; align-items: center; gap: var(--space-16); width: 100%;
  padding: var(--space-12); margin-bottom: 10px; cursor: pointer; text-align: left;
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-subtle); border-radius: var(--r);
}
.avisa-sheet .who-row .ic { display: flex; width: 24px; height: 24px; flex: 0 0 auto; color: var(--ok); }
.avisa-sheet .who-row .nm { flex: 1; font-weight: 700;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh); }
/* The small toggle variant his sheet uses: 40x24 with an 18px handle. */
.switch.sm { width: 40px; height: 24px; margin-top: 0; }
.switch.sm::after { width: 18px; height: 18px; top: 3px; left: 3px; }
.switch.sm.on::after { transform: translateX(16px); }

/* Location as a standing block rather than a button floating above the list:
 * it says what happens on its own and offers the manual resend underneath. */
.loc-block { border: 1px solid var(--color-border-subtle); border-radius: var(--r);
  background: var(--color-surface-raised); padding: var(--space-16); }
.loc-block .top { display: flex; gap: var(--space-12); align-items: flex-start; }
.loc-block .halo { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
  background: var(--color-brand-subtle); color: var(--ok);
  display: flex; align-items: center; justify-content: center; }
.loc-block .again { display: block; width: 100%; margin-top: var(--space-12);
  border: none; background: transparent; cursor: pointer; font-family: var(--font-body);
  font-weight: 700; font-size: calc(var(--body-lg) * var(--scale));
  color: var(--color-brand-text); padding: var(--space-8); }

/* progress dots for the follow-up sequence */
.progress { display: flex; gap: 6px; justify-content: center; margin: 4px 0 18px; }
.progress i { width: 8px; height: 8px; border-radius: 50%; background: var(--color-border-subtle); }
.progress i.on { background: var(--color-brand-fill); }
.progress i.done { background: var(--color-brand-fill); opacity: .5; }

.receipt { background: var(--color-surface-base); border-radius: 14px; padding: 16px; margin: 16px 0; }
.receipt .row { display: flex; justify-content: space-between; padding: 6px 0; }
.receipt .row .k { color: var(--color-text-muted); }
.receipt .row .v { font-weight: 700; text-align: right; }

.success-mark { width: 88px; height: 88px; border-radius: 50%; background: var(--color-brand-fill); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 46px; margin: 12px auto 8px; }

/* ------------------------------------------------------ emergency / panic -- */
/* Press-and-hold to arm: a fill sweeps left-to-right over the hold duration. */
.hold-btn {
  position: relative; overflow: hidden; width: 100%; min-height: 68px; margin: 20px 0 4px;
  border: 2px solid var(--danger); border-radius: 18px; background: var(--danger); color: #fff;
  font-family: inherit; font-size: calc(17px * var(--scale)); font-weight: 800; cursor: pointer;
  touch-action: none; user-select: none; -webkit-user-select: none;
}
.hold-btn .hold-label { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; gap: 8px; height: 68px; }
.hold-btn .hold-fill { position: absolute; inset: 0; width: 0; background: rgba(0,0,0,.28); z-index: 0; }
.hold-btn.holding .hold-fill { animation: holdfill 1.2s linear forwards; }
.hold-btn.holding { box-shadow: 0 0 0 4px rgba(178,31,45,.25); }
/* Inside the Avisa sheet the hold is not the panic button: it is the primary
 * action colour, with his 76px pill radius. Red there would read as a second
 * emergency control sitting next to the first. */
.avisa-sheet .hold-btn {
  border-color: var(--color-brand-fill); background: var(--color-brand-fill);
  color: var(--color-text-on-brand); border-radius: 76px; min-height: 55px; margin: var(--space-8) 0 0;
  font-size: calc(var(--body-lg) * var(--scale)); letter-spacing: .16px;
}
.avisa-sheet .hold-btn .hold-label { height: 55px; }
.avisa-sheet .hold-btn.holding { box-shadow: 0 0 0 4px rgba(236,106,13,.28); }
@keyframes holdfill { from { width: 0; } to { width: 100%; } }

.em-pulse { width: 96px; height: 96px; border-radius: 50%; margin: 6px auto 0; background: var(--danger);
  display: flex; align-items: center; justify-content: center; animation: empulse 1.3s infinite; }
.em-pulse::after { content: "🔴"; font-size: 30px; }
@keyframes empulse { 0% { box-shadow: 0 0 0 0 rgba(178,31,45,.5); } 70% { box-shadow: 0 0 0 26px rgba(178,31,45,0); } 100% { box-shadow: 0 0 0 0 rgba(178,31,45,0); } }
.wave.danger span { background: var(--danger); }

/* --------------------------------------------------- know-your-rights video -- */
.video-slot {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  width: 100%; aspect-ratio: 16 / 9; margin: 4px 0 18px;
  background: #14110e; color: #fff; border-radius: 16px; border: 2px dashed #4a453f;
}
.video-slot .play { width: 56px; height: 56px; border-radius: 50%; background: rgba(255,255,255,.16);
  display: flex; align-items: center; justify-content: center; font-size: 22px; padding-left: 4px; }
.video-slot span:last-child { font-size: calc(13px * var(--scale)); opacity: .8; }

/* vault document preview (placeholder — real files are encrypted, member-held) */
.doc-preview {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 44px 0; margin: 4px 0 16px;
  background: #f1eee9; border: 2px dashed var(--color-border-subtle); border-radius: 16px; color: var(--color-text-muted);
}
.doc-preview .pg { font-size: 44px; }
.doc-preview span:last-child { font-size: calc(13px * var(--scale)); }

/* -------------------------------------------- added 2026-08-10 (engagement) --
 * .chip  - a small status label (document expiry).
 * .pill  - "planned" marker on the deliberately-stubbed appointments screen, so
 *          it reads as planned rather than unfinished.
 */
.chip {
  display: inline-block; font-size: calc(13px * var(--scale)); font-weight: 700;
  padding: 4px 10px; border-radius: 999px;
  background: var(--color-border-subtle); color: var(--color-text-secondary);
}
.chip.warn { background: #fdeaea; color: var(--danger); }
.pill {
  display: inline-block; font-size: calc(13px * var(--scale)); font-weight: 700;
  padding: 6px 14px; border-radius: 999px;
  background: var(--color-brand-fill); color: var(--color-text-on-brand);
}

/* ------------------------------------------- home digest (added 2026-08-10) --
 * Replaces the two mismatched buttons that used to sit in the review card: an
 * attention row is one tap target with an optional dismiss, so the rows line up
 * however many there are.
 */
.sec {
  font-size: calc(14px * var(--scale)); font-weight: 800; color: var(--color-text-secondary);
  margin: 22px 0 8px; letter-spacing: .01em;
}
.att-card { padding: 0; overflow: hidden; }
.att-row { display: flex; align-items: stretch; border-bottom: 1px solid var(--color-border-subtle); }
.att-row:last-child { border-bottom: 0; }
.att-main {
  flex: 1; display: flex; align-items: center; gap: 12px;
  background: none; border: 0; font: inherit; color: var(--color-text-primary); text-align: left;
  padding: 16px 6px 16px 16px; cursor: pointer; min-height: var(--tap);
}
.att-main .ic { font-size: 22px; flex: none; }
.att-main .txt { flex: 1; font-weight: 600; }
.att-main .chev { color: var(--color-text-muted); font-size: 22px; }
.att-x {
  flex: none; width: 52px; background: none; border: 0; border-left: 1px solid var(--color-border-subtle);
  color: var(--color-text-muted); font-size: 17px; cursor: pointer;
}
.att-x:active { background: var(--color-border-subtle); }

/* The newest announcement, previewed on home so opening the app always shows
 * something worth reading. */
.news-peek {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: var(--r);
  padding: 16px; font: inherit; color: var(--color-text-primary);
}
.news-peek .meta { display: block; font-size: calc(13px * var(--scale)); color: var(--color-text-muted); }
.news-peek .ttl { display: block; font-weight: 800; margin: 4px 0 4px; }
.news-peek .line {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; color: var(--color-text-secondary);
}
.news-peek .more { display: block; margin-top: 10px; font-weight: 800; color: var(--color-brand-fill); }

/* The help hero is an action now, not the page's subject, so it sits lower and
 * lighter than the old story hero. */
.hero-help { margin-top: 6px; }

/* ------------------------------------- chrome restructure (2026-08-11) ------
 * Four things wanted permanent space (identity, freshness, help, emergency) and a
 * phone affords two zones. So: identity + notifications on top, the two help
 * paths pinned at the bottom, and the whole scroll area left to navigation.
 */
.appbar { position: relative; }
.megaphone {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  background: transparent; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  line-height: 1; color: var(--color-text-primary);
}
.megaphone:active { background: rgba(41, 40, 36, .06); }
/* Deliberately NOT red. Red belongs to the emergency path; a document expiring
 * is not an emergency and must not borrow that alarm. */
.megaphone .badge {
  position: absolute; top: 4px; right: 4px; min-width: 18px; height: 18px;
  border-radius: 999px; background: var(--aqua-600); color: #fff;
  font-size: 11px; font-weight: 700; line-height: 18px; padding: 0 4px;
  border: 2px solid var(--color-surface-base);
}
/* leave room for the megaphone so a long Sponsor name never slides under it */
.appbar .titles { padding-right: 52px; }

/* Permanent bottom navigation (2026-08-21). Replaced the two-button action bar
 * after the consul dead-ended in the prototype. Four fixed tabs, big targets,
 * label under every icon: an icon alone is not readable by someone who does not
 * already know what it means. Emergency is a tab so it is always one tap away,
 * and it is the one tab allowed to carry colour. */
.tabbar {
  position: sticky; bottom: 0; z-index: 5; display: flex;
  padding: 6px 6px calc(6px + env(safe-area-inset-bottom, 0px));
  background: var(--color-surface-base); border-top: 1px solid var(--color-border-subtle);
}
.tabbar .tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-height: 58px; padding: 8px 2px; border: 0; border-radius: 12px;
  background: transparent; font: inherit; color: var(--color-text-secondary); cursor: pointer;
}
.tabbar .tab .ic { font-size: 21px; line-height: 1; }
.tabbar .tab .lb { font-size: calc(11.5px * var(--scale)); font-weight: 700; }
.tabbar .tab.on { color: var(--color-brand-fill); background: rgba(0, 0, 0, .04); }
.tabbar .tab.em { color: var(--danger); }
.tabbar .tab.em.on { color: var(--danger); background: #fdeaea; }
.tabbar .tab:active { transform: scale(.97); }

/* Papers, C2. A checklist of what the person HAS. Never an upload: no camera, no
 * file picker. "Nada más el listado de los documentos, pero no el documento." */
.papers { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.paper {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 54px; padding: 10px 12px; text-align: left; cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 12px;
  font: inherit; font-size: calc(15px * var(--scale)); color: var(--color-text-primary);
}
.paper .bx {
  flex: none; width: 24px; height: 24px; border-radius: 7px;
  border: 2px solid var(--color-border-subtle); background: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 14px; color: transparent;
}
.paper .ic { flex: none; font-size: 19px; }
.paper .lb { flex: 1; }
.paper.on { border-color: var(--color-brand-fill); background: #f3f6f3; }
.paper.on .bx { background: var(--color-brand-fill); border-color: var(--color-brand-fill); color: #fff; }
.paper:active { transform: scale(.99); }

/* Automatic re-routing, stated plainly on the case. The member could not tell
 * that a decline had already been handled for them. */
.reroute {
  margin-top: 10px; padding: 12px 13px; border-radius: 12px;
  background: #fff8ec; border: 1px solid #f0dcb8; text-align: left;
}
.reroute .rt-t { font-weight: 800; font-size: calc(15px * var(--scale)); }
.reroute .rt-b { margin-top: 4px; font-size: calc(14.5px * var(--scale)); }
.reroute .rt-n { margin-top: 6px; font-size: calc(13px * var(--scale)); color: var(--color-text-secondary); }

/* One line of freshness on home. The badge carries the signal; this carries the
 * headline. Anything more belongs in Avisos. */
.peek-line {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: var(--r);
  padding: 14px 14px; font: inherit; color: var(--color-text-primary); text-align: left; cursor: pointer;
}
.peek-line .dot { width: 9px; height: 9px; border-radius: 50%; background: #e08a1e; flex: none; }
.peek-line .ttl {
  flex: 1; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.peek-line .chev { color: var(--color-text-muted); font-size: 20px; }

/* ------------------------------- emergency capture control (2026-08-11) -----
 * The stop control used to be a white outline button floating under the card,
 * which was hard to find. Best practice for a capture control: it lives on the
 * card that owns the state, sits next to the timer, has real contrast, is big
 * enough to hit under stress, and never asks for confirmation. Not brand-primary
 * either: stopping is not the encouraged action, it just has to be findable.
 */
.rec-stop {
  flex: none; width: 48px; height: 48px; border-radius: 50%;
  background: var(--danger); border: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.rec-stop .sq { width: 16px; height: 16px; border-radius: 3px; background: #fff; display: block; }
.rec-stop:active { filter: brightness(.9); }
/* the word, so the icon is never the only signal */
.rec-stop-label {
  display: block; width: 100%; margin-top: 10px; padding: 10px 0;
  background: none; border: 0; border-top: 1px solid var(--color-border-subtle);
  font: inherit; font-size: calc(15px * var(--scale)); font-weight: 700;
  color: var(--danger); cursor: pointer;
}

/* the alert that already went out when the button was armed: one line, always
   visible, so the roster does not need to be a whole tab */
.armed-line {
  background: #eef5ef; border: 1px solid #cfe3d4; border-radius: 12px;
  padding: 10px 14px; font-size: calc(14px * var(--scale)); color: #17472a;
  margin-bottom: 12px;
}
.draft-head {
  font-weight: 800; font-size: calc(19px * var(--scale));
  padding: 12px 0 2px; text-align: center;
}
/* the resolve, distinct from the danger updates because it ends the episode */
.btn-safe {
  background: var(--color-surface-raised); border: 2px solid var(--ok); color: var(--ok);
  display: block; text-align: center; padding: 14px;
}
.btn-safe .sub {
  display: block; font-size: calc(13px * var(--scale)); font-weight: 500;
  color: var(--color-text-secondary); margin-top: 4px;
}

.loc-again { margin-bottom: 6px; }


/* The one unmissable action on Home: ask for help. Big, branded, labelled with
 * the consul's own words ("Cuéntanos qué te pasó"). */
.ask {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  min-height: 84px; padding: 18px; border: 0; border-radius: 20px; cursor: pointer;
  background: var(--color-brand-fill); color: var(--color-text-on-brand); font: inherit;
}
.ask .ic { font-size: 30px; flex: none; }
.ask .txt { flex: 1; }
.ask .txt .t { display: block; font-weight: 800; font-size: calc(20px * var(--scale)); }
.ask .txt .s { display: block; margin-top: 3px; opacity: .9; font-size: calc(14px * var(--scale)); line-height: 1.35; }
.ask:active { transform: scale(.99); }


/* Step indicator for the send flow (2026-08-21). Words plus a bar, never bare
 * numbers: "0-1-2-3-4" is abstract for this audience. Not clickable, because
 * jumping around a flow is how people get lost in it. */
.stepbar { margin: 0 0 var(--space-24); text-align: center; }
.stepbar .lb {
  font-family: var(--font-body);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  font-weight: 700; color: var(--aqua-600); margin-bottom: var(--space-16);
}
/* One pip per step rather than a percentage fill. A filled bar answers "how far
 * along am I"; five pips also answer "how much is left", which is the question
 * that decides whether someone abandons. */
.stepbar .pips { display: flex; gap: var(--space-8); justify-content: center; }
.stepbar .pip {
  width: 40px; height: 8px; border-radius: 72px;
  background: var(--color-surface-sunken); transition: background .3s ease;
}
.stepbar .pip.on { background: var(--aqua-500); }

/* "Ve lo que escuchamos": a disclosure, closed by default. A wall of transcript
 * is intimidating and invites people to judge their own Spanish; hiding it
 * entirely breaks trust. One tap, and editable once open. */
.disclose {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin: 4px 0 10px; padding: 14px 16px; cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 14px;
  font: inherit; font-size: calc(15px * var(--scale)); font-weight: 700; color: var(--color-brand-fill);
}
.disclose .cv { font-size: 16px; color: var(--color-text-muted); }
.disclose:active { transform: scale(.99); }

/* The paused recorder. The big button carries pause/resume; finishing is its own
 * primary button, because pausing and finishing are different intentions. */
.wave.still span { animation: none; opacity: .35; }

/* A section heading that carries its own control, so the shortlist filter sits
 * with the list it filters instead of floating above the whole screen. */
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 22px 0 10px;
}
/* The section head wraps on a narrow phone, so the filter gets its own line and
 * the select takes the width it needs. Capping it truncated the Spanish label. */
.filter { display: flex; align-items: center; gap: 7px; flex: 1 1 100%; min-width: 0; }
.filter .fl {
  font-size: calc(12.5px * var(--scale)); font-weight: 700; color: var(--color-text-muted);
}
.filter select {
  font: inherit; font-size: calc(13.5px * var(--scale)); font-weight: 600;
  color: var(--color-text-primary); background: var(--color-surface-raised);
  border: 1px solid var(--color-border-subtle); border-radius: 10px;
  padding: 7px 26px 7px 10px; flex: 1 1 auto; min-width: 0; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-text-muted) 50%),
                    linear-gradient(135deg, var(--color-text-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}


/* The ladder ran out. Same shape as the re-routing notice but neutral rather than
 * amber, because nothing is in flight and nothing is wrong: a person still calls. */
.reroute.exh { background: #f4f2ee; border-color: var(--color-border-subtle); }

/* What our text message actually looks like, shown before one arrives. The
 * message says nothing by design, and to somebody who gets defrauded weekly an
 * empty text with a link is indistinguishable from a scam. */
.smsdemo { margin-top: 4px; }
.smsdemo .bub {
  display: inline-block; max-width: 92%; padding: 12px 15px;
  background: #e8ebf5; border-radius: 18px 18px 18px 5px;
  font-size: calc(15px * var(--scale)); line-height: 1.4; text-align: left;
}
.smsdemo .lk { color: var(--color-brand-fill); text-decoration: underline; word-break: break-all; }


/* An option on a case that costs the member something, so the cost is printed
 * under the label rather than discovered later. */
.opt {
  display: block; width: 100%; margin-top: 8px; padding: 13px; cursor: pointer;
  text-align: left; font: inherit; color: var(--color-text-primary);
  background: var(--color-surface-raised); border: 1.5px solid var(--color-border-subtle); border-radius: 12px;
}
.opt .ot { display: block; font-weight: 800; font-size: calc(15px * var(--scale)); color: var(--color-brand-fill); }
.opt .ow { display: block; margin-top: 3px; font-size: calc(13.5px * var(--scale)); color: var(--color-text-secondary); line-height: 1.4; }
.opt:active { transform: scale(.99); }


/* Icons (Remix Icon, inlined). They take their colour from the text colour, so
 * an icon inside a coloured button or a muted line needs no extra rule. */
.i { display: inline-block; vertical-align: middle; flex: none; fill: currentColor; }
.ic .i, .tile .ic .i { display: block; }


/* Home, Idea B (2026-08-31). The live case comes first, then the way to start
 * one, then everything else. */
.case-peek {
  display: block; width: 100%; text-align: left; cursor: pointer; font: inherit;
  color: var(--color-text-primary); background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle);
  border-radius: var(--r); padding: var(--space-16); box-shadow: var(--shadow);
}
.case-peek .top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); }
.case-peek .ttl {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-sm) * var(--scale)); margin-top: var(--space-8);
}
.case-peek .nx { margin-top: var(--space-8); font-size: calc(var(--body-md) * var(--scale)); color: var(--color-text-secondary); line-height: 1.45; }
.case-peek:active { transform: scale(.995); }
.chip.state { font-size: calc(var(--body-sm) * var(--scale)); font-weight: 700; padding: 4px 10px; border-radius: 999px; }
.chip.state.review, .chip.state.sent { background: var(--amber-100); color: var(--amber-700); }
.chip.state.engaged { background: var(--green-100); color: var(--green-700); }
.chip.state.searching { background: var(--orange-100); color: var(--orange-700); }
.chip.state.exhausted { background: var(--red-100); color: var(--red-700); }
.chip.state.paused { background: var(--neutral-300); color: var(--neutral-800); }
h2.sec { margin: var(--space-24) 0 var(--space-12); font-size: calc(var(--title-sm) * var(--scale)); }

/* Five tabs, with help raised in the middle. It is not red: the emergency is
 * used rarely, and a red button shouting from every screen makes somebody feel
 * bad every time they open an app they already open on a bad week. Red is kept
 * for the state where something is actually happening. */
.tabbar .tab.mid .ic {
  width: 52px; height: 52px; margin-top: -22px;
  border-radius: 50%; background: var(--color-brand-fill); color: var(--color-text-on-brand);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(236, 106, 13, .34);
  border: 3px solid var(--color-surface-base);
}
.tabbar .tab.mid { color: var(--color-brand-fill); }
.tabbar .tab.mid .lb { margin-top: 2px; }
.tabbar .tab.mid.on .ic { background: var(--color-brand-text); }


/* On Home the three accesses sit in one row, as the design has them: three equal
 * tiles rather than a 2-up grid that leaves the third stranded on its own line. */
.screen .tiles.three { grid-template-columns: repeat(3, 1fr); gap: var(--space-12); }
.screen .tiles.three .tile { min-height: 96px; padding: var(--space-12) var(--space-8); }
.screen .tiles.three .lbl { font-size: calc(var(--body-sm) * var(--scale)); line-height: 1.25; text-align: center; }
.ask { margin-top: var(--space-16); }


/* ============================================================================
 * Home, measured from Figma (node 214:2068) rather than eyeballed. Every value
 * below is read from the design, not approximated: the two glows and their
 * colours, the halo behind each icon, the 104px tile, the 20px section heading,
 * the chip colours per state, and the 24px radius on the ask bar.
 * ========================================================================= */

/* The two blurred shapes are the design's own SVGs, downloaded from Figma. Orange
 * (#F2BC86) enters from the top left, green (#118F76) rises from the bottom
 * right, both blurred at 125. A vertical linear gradient was not the same thing. */
#app { position: relative; }
#app::before, #app::after {
  content: ""; position: absolute; z-index: 0; pointer-events: none;
  background-repeat: no-repeat; background-size: 100% 100%;
}
#app::before {                       /* orange, top left, rotated as in the design */
  background-image: url("./assets/bg/glow-top.svg");
  width: 647px; height: 705px; left: -179px; top: -140px;
  transform: rotate(11.85deg);
}
#app::after {                        /* green, rising from the bottom right */
  background-image: url("./assets/bg/glow-bottom.svg");
  width: 533px; height: 609px; left: 142px; top: 53%;
}
.appbar, .screen, .tabbar { position: relative; z-index: 1; }

/* Section heading: IBM Plex Sans SemiBold 20/28, #050505. It was 16px. */
h2.sec {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(20px * var(--scale)); line-height: 28px;
  color: #050505; margin: var(--space-24) 0 var(--space-12);
}

/* Case card on Home */
.case-peek {
  padding: var(--space-16); border-radius: 16px; gap: var(--space-12);
  border: 1px solid #dfdcd4; box-shadow: 0 4px 20px rgba(218, 223, 227, .32);
}
.case-peek .ttl {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(20px * var(--scale)); line-height: 28px; color: #050505;
  margin-top: 0;
}
.case-peek .top { margin-bottom: var(--space-12); }
.case-peek .top .muted { font-weight: 600; font-size: calc(14px * var(--scale)); line-height: 20px; color: #5d5a56; }
.case-peek .nx { margin-top: var(--space-4); font-weight: 600; font-size: calc(14px * var(--scale)); line-height: 20px; color: #43423d; }

/* Status chip: 20px icon plus Mulish Bold 12/18 with 0.12 tracking, radius 8. */
.chip.state {
  display: inline-flex; align-items: center; gap: var(--space-8);
  padding: var(--space-4) var(--space-8); border-radius: 8px;
  font-family: var(--font-body); font-weight: 700;
  font-size: calc(12px * var(--scale)); line-height: 18px; letter-spacing: .12px;
}
.chip.state.review, .chip.state.sent   { background: #fef6e7; color: #895b06; }
.chip.state.engaged                    { background: #f2f9f3; color: #006228; }
.chip.state.searching                  { background: #fef6e7; color: #895b06; }
.chip.state.exhausted                  { background: var(--red-50); color: var(--red-700); }
.chip.state.paused                     { background: var(--neutral-300); color: var(--neutral-800); }

/* Every icon that leads a card sits in a round pale halo. This is the single
 * biggest reason the first pass did not look like the design. */
.halo {
  display: inline-flex; align-items: center; justify-content: center;
  padding: var(--space-8); border-radius: 32px; background: #fef2e7;
  color: var(--color-brand-fill); flex: none;
}
.ask .halo { background: #fef0e7; }

/* Ask bar: radius 24, padding 16, gap 20, title 20/28 white, sub 14/20 white. */
.ask {
  gap: var(--space-20); padding: var(--space-16); border-radius: 24px;
  margin-top: var(--space-16); align-items: center;
}
.ask .txt .t {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(20px * var(--scale)); line-height: 28px;
}
.ask .txt .s {
  margin-top: var(--space-8); opacity: 1;
  font-weight: 600; font-size: calc(14px * var(--scale)); line-height: 20px;
}

/* Access tiles: 104 wide, gap 8, centred, halo above an IBM Plex 14/20 label. */
.screen .tiles.three {
  display: flex; gap: var(--space-8); align-items: stretch;
}
.screen .tiles.three .tile {
  flex: 1 1 0; min-width: 0; min-height: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-8); padding: var(--space-12) var(--space-8);
  border: 1px solid #dfdcd4; border-radius: 16px; background: var(--color-surface-raised);
  box-shadow: none;
}
.screen .tiles.three .lbl {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(14px * var(--scale)); line-height: 20px; letter-spacing: .14px;
  text-align: center; color: #292824;
}

/* Navigation bar, measured: 80 tall, top border #dfdcd4, items pt 12 pb 16 with
 * a 4px gap, 24px icon, Mulish SemiBold 12/18 at 0.12 tracking, active #ec6a0d
 * and inactive #8c8a84. The middle item is NOT a filled circle: Doug's call, so
 * that the app is not shouting an alarm colour on every screen. */
.tabbar {
  background: var(--color-surface-raised); border-top: 1px solid #dfdcd4;
  gap: var(--space-8); padding: 0 var(--space-8) env(safe-area-inset-bottom, 0px);
}
.tabbar .tab {
  flex: 1 1 0; min-width: 0; height: 80px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-4); padding: var(--space-12) 2px var(--space-16);
  background: transparent; border: 0; cursor: pointer; color: #8c8a84;
}
.tabbar .tab .lb {
  font-family: var(--font-body); font-weight: 600;
  font-size: calc(12px * var(--scale)); line-height: 18px; letter-spacing: .12px;
}
.tabbar .tab.on { color: var(--color-brand-fill); background: transparent; }
.tabbar .tab.mid { color: var(--color-brand-fill); }
.tabbar .tab.mid .ic {
  width: auto; height: auto; margin: 0; border: 0; border-radius: 0;
  background: transparent; box-shadow: none; color: inherit;
}
.tabbar .tab.mid.on .ic { background: transparent; }

/* Home's app bar: an empty 40px slot, a centred title, then the actions. */
.appbar.home { height: 64px; padding: var(--space-8) var(--space-4); }
.appbar.home .slot { width: 40px; flex: none; }
.appbar.home .ttl {
  flex: 1 1 0; text-align: center; min-width: 0;
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(20px * var(--scale)); line-height: 28px; color: #292824;
}

/* The endorsement line. Quiet on purpose: the design gives Home's bar no room
 * for a brand, but "BrioAI-branded, ally as a badge" is a product decision, so
 * it is stated here rather than dropped. */
.endorse {
  position: relative; z-index: 1; text-align: center;
  padding: 0 var(--space-16) var(--space-8);
  font-size: calc(11px * var(--scale)); line-height: 16px; color: var(--color-text-muted);
}
.appbar.home .slot .seal { width: 28px; height: 28px; color: var(--color-brand-fill); }


/* ---------------------------------------------------------------- carousels --
 * Three of them carry Home. A scroll-snapped row, native touch scrolling, dots
 * beneath as a position readout rather than as controls. The heading is the link
 * to the full page, so the carousel is a way across and never the only way in.
 * The rail bleeds to both screen edges so a half-visible next card tells you
 * there is more, which is the only affordance that reliably teaches a swipe. */
.carousel { margin-bottom: var(--space-8); }
.sec-link {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-8);
  width: 100%; background: none; border: 0; padding: 0; cursor: pointer; font: inherit;
  color: var(--color-text-primary); text-align: left;
}
.rail {
  display: flex; gap: var(--space-12); overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  padding: var(--space-4) var(--pad) var(--space-12);
  margin: 0 calc(-1 * var(--pad));
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.card-slide {
  flex: 0 0 84%; max-width: 300px; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: var(--space-4);
  background: var(--color-surface-raised); border: 1px solid #dfdcd4; border-radius: 16px;
  padding: var(--space-16); box-shadow: 0 4px 20px rgba(218, 223, 227, .32);
  text-align: left; cursor: pointer; font: inherit; color: var(--color-text-primary);
}
.card-slide .top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); margin-bottom: var(--space-4); }
.card-slide .cs-t {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(20px * var(--scale)); line-height: 28px; color: #050505;
}
.card-slide .cs-t.sm { font-size: calc(16px * var(--scale)); line-height: 24px; }
.card-slide .cs-b {
  font-weight: 600; font-size: calc(14px * var(--scale)); line-height: 20px; color: #43423d;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card-slide:active { transform: scale(.995); }

.card-slide.right { flex-basis: 62%; }
.halo.sm { padding: var(--space-8); }


/* A halo inside a column card would stretch to the card's width without this. */
.card-slide .halo { align-self: flex-start; margin-bottom: var(--space-4); }


/* ------------------------------------------------------------------- splash --
 * The bridge photograph under a dark scrim. The scrim is doing real work: the
 * photograph has its own bright and dark areas and white type over an unscrimmed
 * photo is unreadable on a phone held at arm's length in daylight. */
.screen.splash {
  position: relative; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; min-height: 100%; padding: var(--space-32);
  background: #25231f; color: #fff; overflow: hidden;
}
.screen.splash::after {
  content: ""; position: absolute; inset: 0; z-index: 0; background: var(--color-brand-fill);
}
.screen.splash::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: url("./assets/bg/bridge.jpg") center / cover no-repeat;
  mix-blend-mode: overlay; opacity: .2;
}
.screen.splash > * { position: relative; z-index: 2; }
.sp-mark { color: #fff; margin-bottom: var(--space-16); }
.sp-mark .seal { width: 84px; height: 84px; }
.sp-name {
  font-family: "Manrope", var(--font-title); font-weight: 500;
  font-size: calc(44px * var(--scale)); line-height: 56px; letter-spacing: -.44px;
  color: #fff; margin: 0 0 var(--space-12);
}
.sp-tag {
  font-size: calc(16px * var(--scale)); line-height: 26px;
  color: rgba(255,255,255,.9); max-width: 300px; margin: 0 0 var(--space-32);
}
.sp-cta { width: 100%; max-width: 320px; }
/* A growing middle so the lockup centres in the space above the footer. It was
 * packing to the top, because the footer's auto margin ate all the free space. */
.sp-main {
  flex: 1 1 auto; width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0;
}
.sp-main > * { flex: none; }
/* margin-top:auto rather than absolute positioning: the splash is a flex column,
 * so the footer is simply pushed to the bottom and cannot land on the button. */
.sp-foot {
  margin-top: auto; padding-top: var(--space-32); width: 100%;
  display: flex; flex-direction: column; align-items: center; gap: var(--space-12);
}
.sp-ally {
  font-size: calc(12px * var(--scale)); line-height: 18px;
  color: rgba(255,255,255,.85); text-align: center;
}
.sp-brio {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: calc(10px * var(--scale)); color: rgba(255,255,255,.7);
}
.sp-brio img { height: 17px; width: auto; }


/* --- fitting three carousels on a 760 phone (2026-08-31) -------------------
 * Chrome takes about 172 of the 760: app bar 64, endorsement 28, navigation 80.
 * That leaves roughly 190 per carousel, so a rail is ~132 and the type drops a
 * step. The previous sizes were the Home case-card spec, which is right for one
 * card on its own and far too big for three rows of them. */
.carousel { margin-bottom: 0; }
.carousel h2.sec { margin: var(--space-12) 0 var(--space-8); }
.rail { padding: 2px var(--pad) var(--space-8); }
.card-slide {
  flex-basis: 78%; max-width: 268px; gap: 2px;
  padding: var(--space-12) var(--space-16);
}
.card-slide .cs-t {
  font-size: calc(16px * var(--scale)); line-height: 22px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card-slide .cs-t.sm { font-size: calc(15px * var(--scale)); line-height: 20px; }
.card-slide .cs-b {
  font-size: calc(13px * var(--scale)); line-height: 18px; -webkit-line-clamp: 2;
}
.card-slide .muted.small { font-size: calc(11.5px * var(--scale)); line-height: 16px; }
.card-slide .top { margin-bottom: 2px; }
.chip.state { font-size: calc(11.5px * var(--scale)); padding: 3px var(--space-8); }
.card-slide.right { flex-basis: 56%; }
.card-slide .halo { padding: 6px; margin-bottom: 2px; }
.screen { padding-top: var(--space-8); }

/* The last carousel's dots were sliding under the navigation bar. The screen's
 * 28px bottom padding was sized for a scrolling page; Home does not scroll. */
.screen { padding-bottom: var(--space-4); }
.endorse { padding-bottom: var(--space-4); }
.carousel:last-child .rail { padding-bottom: var(--space-4); }

/* The rights cards are a label and a hint, so they can be the shortest of the
 * three: the halo shrinks, the hint clamps to one line, and the card lays the
 * halo beside the text rather than above it. */
.card-slide.right { flex-direction: row; align-items: center; gap: var(--space-12); padding: var(--space-12); }
.card-slide.right .halo { margin: 0; padding: 6px; align-self: center; }
.card-slide.right .cs-t { -webkit-line-clamp: 1; }
.card-slide.right .cs-b { -webkit-line-clamp: 1; }
.card-slide.right > div:not(.halo) { min-width: 0; }
.card-slide.right .rt-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }


/* The first card sat 20px left of the headings. Cause: scroll-snap aligns a
 * card's start edge to the scrollport's start, which ignores the rail's own
 * padding, so the browser scrolled the padding away. scroll-padding tells
 * snapping where the inset actually is. */
.rail { scroll-padding-left: var(--pad); scroll-padding-right: var(--pad); }

/* One line of body, not two. In a horizontal carousel people are scanning, not
 * reading: the card's job is recognition, so you know whether to tap. Two lines
 * invite reading and make the page feel like work. */
.card-slide .cs-b { -webkit-line-clamp: 1; }

/* Para ti gets its category as a coloured mark rather than a photograph. Photos
 * would need stock imagery of this community, which the member narrative rules
 * out, and they cost weight on the phone this is built for. The category is
 * already in the data, so it costs nothing and it makes the row scannable. */
.card-slide .kind {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 2px;
  font-family: var(--font-body); font-weight: 700;
  font-size: calc(11px * var(--scale)); line-height: 16px; letter-spacing: .3px;
  text-transform: uppercase;
}
.card-slide .kind .k-dot {
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
}
.kind.servicio { color: var(--aqua-700); }
.kind.servicio .k-dot { background: var(--aqua-50); }
.kind.derechos { color: var(--amber-700); }
.kind.derechos .k-dot { background: var(--amber-50); }
.kind.aviso { color: var(--orange-700); }
.kind.aviso .k-dot { background: var(--orange-50); }

.rail.solo .card-slide { flex-basis: 100%; max-width: none; }
/* The ask, used as a block on the cases page rather than as a carousel card. */
.screen > .ask { margin: 0 0 var(--space-16); }

/* Nothing outside the app may scroll on a phone, or the navigation goes with it. */
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; }

/* The design's splash is a loading screen with no button, so it never had to
 * solve this: a brand-orange button on a brand-orange field is invisible. White
 * with orange text is the inverse of the primary button and reads at a glance. */
/* Not pure white: on a saturated orange field it glares. Orange 50 from the
 * palette is a warm off-white that sits in the same family and still reads at a
 * glance, with orange 600 for the text so the contrast holds. */
.screen.splash .sp-cta .btn-primary {
  background: var(--orange-50); color: var(--orange-600);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .14);
}
.screen.splash .sp-cta .btn-primary:active { background: var(--orange-100); }

/* The loading state a returning member sees: the design's own spinner and label,
 * with no button, because there is nothing to decide. */
.sp-load { display: flex; flex-direction: column; align-items: center; gap: var(--space-16); }
.sp-loadtext { font-weight: 700; font-size: calc(14px * var(--scale)); line-height: 20px; color: #fff; }
.spin {
  width: 44px; height: 44px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,.32); border-top-color: #fff;
  animation: spin 900ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation-duration: 2.4s; } }


/* The family plan's rows carry halos, and the emergency one is filled: it is the
 * most important thing in the plan and the only one that matters at speed. */
.choice .halo { width: 44px; height: 44px; padding: 0; }
.choice .halo.solid { background: var(--color-brand-fill); color: var(--color-text-on-brand); }
.choice.lead-row { border-color: var(--orange-200); }

/* Orange belongs to Ayúdame in the navigation. An active tab that also went
 * orange competed with it, so being on a tab is shown with ink and weight
 * instead, and the one always-orange item stays the thing your eye finds. */
.tabbar .tab.on { color: var(--color-text-primary); }
.tabbar .tab.on .lb { font-weight: 700; }
.tabbar .tab.mid, .tabbar .tab.mid.on { color: var(--color-brand-fill); }
.tabbar .tab.mid .lb { font-weight: 700; }

/* The wordmark sits small at the top left so the greeting keeps the centre. */
.appbar.home .slot { width: auto; min-width: 40px; }
.appbar.home .wordmark {
  font-family: "Manrope", var(--font-title); font-weight: 500;
  font-size: calc(13px * var(--scale)); line-height: 18px;
  color: var(--color-text-muted); white-space: nowrap; padding-left: var(--space-8);
}


/* The ask card was solid orange and taller than its neighbours, so it shouted
 * rather than invited. White with an orange edge and an orange mark sits at the
 * same weight as the other cards while still being the one that draws the eye. */

/* The page mark that leads a detail screen. It was printing the icon's NAME. */
.page-mark { color: var(--color-brand-fill); margin-bottom: var(--space-8); }

/* The greeting has to sit in the true centre of the bar, not in the space left
 * over beside the wordmark, so it is centred against the bar rather than flowed. */
.appbar.home { position: relative; }
.appbar.home .ttl {
  position: absolute; left: 0; right: 0; text-align: center;
  pointer-events: none; padding: 0 var(--space-56);
}
.appbar.home .slot { flex: 1 1 auto; }
.appbar.home .wordmark {
  font-size: calc(15px * var(--scale)); line-height: 20px;
  color: var(--color-text-secondary); font-weight: 500;
}


/* One roster, three roles, chosen inline. Segmented rather than a dropdown so
 * the whole choice is visible: this is the question the consul says people
 * worry about most, and it should not be hidden behind a tap. */
.roles { display: flex; gap: 6px; margin: 0 0 var(--space-8); }
.roles.wrap { flex-wrap: wrap; margin-top: var(--space-8); }
.role {
  flex: 1 1 0; min-width: 0; padding: 8px 6px; cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 10px;
  font: inherit; font-size: calc(11.5px * var(--scale)); line-height: 16px;
  font-weight: 600; color: var(--color-text-secondary); text-align: center;
}
.roles.wrap .role { flex: 0 1 auto; padding: 8px 12px; }
.role.on { background: var(--orange-50); border-color: var(--color-brand-fill); color: var(--orange-700); }
.role:active { transform: scale(.98); }

/* The executor, once chosen. Stated rather than offered, because it is a single
 * role and the screen should say who holds it. */
.alb.is {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: var(--space-8) var(--space-12); border-radius: 10px;
  background: var(--aqua-50); color: var(--aqua-800);
  font-size: calc(13px * var(--scale)); line-height: 18px;
}
.alb.is .muted { flex: 1 1 100%; color: var(--aqua-700); }

/* The app bar's action: a plus and a word, small, level with the title. Quieter
 * than a full-width button and it belongs to the screen rather than to whichever
 * list happens to be showing. */
.appbar .titles { flex: 1 1 auto; min-width: 0; }
/* Solid orange, not a tinted outline. On Mi gente and Mis bienes this is the
 * one thing the page is asking her to do, and a pale chip in the corner read as
 * a label rather than a button. */
.bar-add {
  flex: none; display: inline-flex; align-items: center; gap: 4px;
  padding: 8px 14px; border-radius: 999px; cursor: pointer;
  background: var(--color-brand-fill); border: 1px solid var(--color-brand-fill);
  color: var(--color-text-on-brand); font: inherit; font-weight: 700;
  font-size: calc(13px * var(--scale)); line-height: 18px;
}
.bar-add:active { background: var(--color-brand-text); border-color: var(--color-brand-text); }

/* The ask card lays its copy beside the mark, not under it: stacked, it stood
 * taller than the case cards next to it. The mark is solid orange, the same
 * treatment as the emergency row in the plan, so the two actions that matter
 * most read the same way. */
.halo.solid { background: var(--color-brand-fill); color: var(--color-text-on-brand); }
.ask-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }


/* ---------------------------------------------------------------- the ask --
 * The last card in Mis casos, and the only card when there are none, so the
 * empty state is the invitation rather than a separate screen.
 *
 * One block on purpose: this had accumulated three competing rule sets across
 * successive passes, which is how it ended up fourteen pixels taller than its
 * neighbours with nothing obviously causing it.
 *
 * Copy beside the mark, not under it. Filled orange mark, like the emergency row
 * in the plan, so the two actions that matter most read the same way. */
.card-slide.ask-slide {
  flex-direction: row; align-items: center; justify-content: flex-start;
  gap: var(--space-12);
  background: var(--color-surface-raised); border: 1px solid var(--color-brand-fill); color: var(--color-text-primary);
  box-shadow: inset 0 0 0 1px var(--color-brand-fill), 0 4px 20px rgba(218, 223, 227, .32);
}
.card-slide.ask-slide .halo {
  align-self: center; margin: 0; flex: none;
  background: var(--color-brand-fill); color: var(--color-text-on-brand);
}
.card-slide.ask-slide .cs-t { color: #050505; }
.card-slide.ask-slide .cs-b { color: var(--color-text-secondary); -webkit-line-clamp: 1; }
.ask-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }

/* Grid, not flex. Flex would not give equal-height cards here: the ask card
 * stretched to the rail's content box while its neighbours stopped at the line,
 * and nowrap, an explicit stretch and matching borders all failed to change it.
 * A single-row grid sizes every column to the tallest by definition, which is
 * exactly what a uniform card rail wants. */
.rail {
  display: grid; grid-auto-flow: column;
  grid-auto-columns: 78%; align-items: stretch;
}
.rail > .card-slide { flex: none; max-width: none; width: 100%; height: auto; }
.rail.solo { grid-auto-columns: 100%; }
[data-rail="rights"] { grid-auto-columns: 54%; gap: var(--space-4); }

/* The recovery phrase, when shown. Monospaced and generously spaced because it
 * has to be copied onto paper accurately by somebody who may be anxious. */
.phrase {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: calc(16px * var(--scale)); line-height: 30px; letter-spacing: .5px;
  background: var(--color-surface-raised); border: 1px dashed var(--color-brand-fill); border-radius: 12px;
  padding: var(--space-16); margin: var(--space-8) 0; word-spacing: 6px;
}
/* The endorsement sits close under the greeting so the two read as one block. */
.endorse { margin-top: -6px; padding-top: 0; }

/* Tighter than a full step: these are rows of cards, and a wide gutter between
 * them reads as a gap in the content rather than as separation. */
.rail { gap: 6px; }

/* ------------------------------------------------ tell-your-story (C1, C2) -- */

/* C1, the three ways to tell it. A card, not a list row: choosing how to speak
 * is the first real decision in the flow, and a chevron row makes it look like
 * navigation you can back out of. No chevron for the same reason. */
.mode-card {
  display: flex; align-items: center; gap: var(--space-24); width: 100%;
  padding: var(--space-16); margin-bottom: var(--space-16); cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 24px;
  font: inherit; text-align: left; transition: transform .1s ease;
}
.mode-card:active { transform: scale(.99); }
.mode-card.on { border: 2px solid var(--color-brand-fill); padding: 15px; }
.mode-card .ic {
  flex: 0 0 auto; display: grid; place-items: center;
  padding: var(--space-8); border-radius: 32px;
  background: var(--orange-50); color: var(--color-brand-fill);
}
.mode-card .bd { flex: 1; min-width: 0; }
.mode-card .hd { display: flex; align-items: center; gap: var(--space-8); margin-bottom: var(--space-8); }
.mode-card .t {
  font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-md) * var(--scale)); line-height: var(--title-md-lh);
  color: var(--color-text-primary);
}
.mode-card .s {
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  font-weight: 600; color: var(--color-text-secondary);
}

/* "Recomendado". Aqua, not orange: orange is the action colour on this screen
 * and a second orange thing next to the chosen card competes with it. */
.pill-rec {
  flex: 0 0 auto; padding: 0 var(--space-8) 2px; border-radius: 38px;
  border: 1px solid var(--aqua-500); color: var(--aqua-600);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
  font-weight: 700; letter-spacing: .12px; white-space: nowrap;
}

/* The privacy reassurance under the three cards. Brand-tinted rather than a
 * grey note, because on this screen it is the reason someone keeps going. */
.alert-brand {
  display: flex; align-items: flex-start; gap: var(--space-12);
  padding: var(--space-12); border-radius: 12px;
  background: var(--orange-50); border: 1px solid var(--color-brand-fill);
  color: var(--orange-600);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  font-weight: 600;
}
.alert-brand .ic { flex: 0 0 auto; display: grid; place-items: center; }

/* The three coaching lines above the recorder. They answer "what am I supposed
 * to say", which is what stalls people in front of a microphone. */
.tiprow {
  display: flex; align-items: center; gap: var(--space-12);
  padding: var(--space-12); margin-bottom: var(--space-12);
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 12px;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  font-weight: 600; color: var(--neutral-800);
}
.tiprow .ic { flex: 0 0 auto; display: grid; place-items: center; color: var(--aqua-600); }

/* While recording, the waveform leads and the control follows. The wave is the
 * proof the app is hearing you; the button is only how you stop. */
.rec-stage { text-align: center; padding: var(--space-8) 0 var(--space-24); }
.rec-stage .wave { height: 120px; gap: 7px; margin: 0 0 var(--space-12); }
.rec-stage .wave span { width: 7px; border-radius: 4px; }
.rec-label {
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  font-weight: 700; color: var(--aqua-600); margin: 0 0 var(--space-24);
  font-variant-numeric: tabular-nums;
}
@keyframes bar-tall { 0%,100%{ height: 24px;} 50%{ height: 108px;} }
.rec-stage .wave span { animation-name: bar-tall; }
.rec-stage .wave.still span { animation: none; opacity: .35; height: 56px; }

/* The saved recording: a player, not a success badge. Hearing it back is what
 * proves we captured what they said, so the control to play it is the screen. */
.player {
  display: flex; align-items: center; gap: var(--space-12); width: 100%;
  padding: var(--space-12) var(--space-16); margin-bottom: var(--space-16);
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 112px;
  font: inherit; cursor: pointer;
}
.player .pb { flex: 0 0 auto; display: grid; place-items: center; color: var(--color-brand-fill); }
.player .wave { flex: 1; height: 32px; gap: 3px; margin: 0; }
.player .wave.still span { opacity: 1; }
.player .wave span { width: 3px; animation: none; }
.player .wave.playing span { animation: bar-short 1s ease-in-out infinite; opacity: 1; }
@keyframes bar-short { 0%,100%{ height: 8px;} 50%{ height: 30px;} }
.player .dur {
  flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 600;
  font-size: calc(var(--body-md) * var(--scale)); color: var(--neutral-800);
}

/* The transcript disclosure. Title and reason stay put; only the chevron moves,
 * so the row does not change shape when it opens. */
.accord {
  display: flex; align-items: center; gap: var(--space-8); width: 100%;
  padding: var(--space-12) var(--space-16); cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 16px;
  font: inherit; text-align: left;
}
.accord .bd { flex: 1; min-width: 0; }
.accord .t {
  display: block; font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-sm) * var(--scale)); line-height: var(--title-sm-lh);
  color: var(--color-text-primary);
}
.accord .s {
  display: block; margin-top: var(--space-4); font-weight: 600;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  color: var(--orange-600);
}
.accord .cv {
  flex: 0 0 auto; display: grid; place-items: center; padding: var(--space-8);
  border-radius: 88px; background: var(--color-surface-base); color: var(--color-text-secondary);
}

/* A row that states one fact the member gave us. The bullet is a marker, not a
 * control, and the divider separates facts without boxing each one. */
.factcard { padding: var(--space-16); }
.factcard .fact { display: flex; align-items: center; gap: var(--space-12); }
.factcard .fact .dot {
  flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--color-brand-fill);
}
.factcard .fact .num {
  flex: 0 0 auto; display: grid; place-items: center; width: 16px; height: 16px;
  border-radius: 50%; background: var(--orange-50); color: var(--orange-600);
  font-size: calc(11px * var(--scale)); font-weight: 700; line-height: 1;
}
.factcard .fact .tx {
  flex: 1; font-weight: 600; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.factcard .sep { height: 1px; background: var(--color-border-subtle); margin: var(--space-12) 0; }

/* A possible legal matter. The tag carries the category so the title can stay
 * in the member's own words rather than in ours. */
.matter { padding: var(--space-12) var(--space-16); margin-bottom: var(--space-8); }
.matter .hd { display: flex; align-items: center; gap: var(--space-8); flex-wrap: wrap; margin-bottom: var(--space-8); }
.matter .t {
  font-family: var(--font-title); font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--title-xs) * var(--scale)); line-height: var(--title-xs-lh);
}
.matter .s { font-weight: 600; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh); }
.pill-tag {
  padding: 0 var(--space-8) 2px; border-radius: 38px;
  border: 1px solid var(--color-brand-fill); color: var(--orange-600);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
  font-weight: 700; white-space: nowrap;
}

/* Who receives the case. A 48px avatar, because an organisation with a face is
 * easier to trust than a name in a list; the circle marks the one chosen. */
.orgcard {
  display: flex; align-items: flex-start; gap: var(--space-16); width: 100%;
  position: relative; padding: var(--space-16); margin-bottom: var(--space-16);
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 16px;
  font: inherit; text-align: left; cursor: pointer;
}
.orgcard.on { border: 2px solid var(--color-brand-fill); padding: 15px; }
.orgcard .av {
  flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%;
  display: grid; place-items: center; background: var(--orange-50); color: var(--color-brand-fill);
}
.orgcard .bd { flex: 1; min-width: 0; padding-right: var(--space-24); }
.orgcard .t {
  display: block; font-family: var(--font-title); font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--title-md) * var(--scale)); line-height: var(--title-md-lh);
}
.orgcard .s {
  display: block; margin-top: var(--space-8); font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.orgcard .pill-rec { display: inline-block; margin-top: var(--space-12); }
.orgcard .rd {
  position: absolute; top: var(--space-12); right: var(--space-12);
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--neutral-300); background: var(--color-surface-raised);
}
.orgcard.on .rd {
  border-color: var(--color-brand-fill); background: var(--color-brand-fill); color: #fff;
  display: grid; place-items: center;
}

/* The sponsor filter. A real select, so it gets the platform's own picker and
 * stays reachable for someone using a screen reader or a switch. */
.showme { margin-bottom: var(--space-24); }
.showme .fl {
  display: block; margin-bottom: var(--space-8); font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-lg) * var(--scale)); line-height: var(--body-lg-lh);
}
.showme select {
  width: 100%; height: 56px; padding: 0 44px 0 var(--space-12);
  background: var(--color-surface-raised); border: 1px solid var(--neutral-500); border-radius: 8px;
  font: inherit; font-weight: 700; color: var(--neutral-800);
  font-size: calc(var(--body-lg) * var(--scale));
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2343423d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 24px;
}

/* The receipt on the Enviado screen: two facts, one rule between them. */
.receipt2 { padding: var(--space-12); margin-bottom: var(--space-24); }
.receipt2 .row { display: flex; align-items: flex-start; gap: var(--space-12);
  font-size: calc(var(--body-lg) * var(--scale)); line-height: var(--body-lg-lh); }
.receipt2 .k { flex: 1; font-weight: 600; color: var(--color-text-secondary); }
.receipt2 .v { font-weight: 700; color: var(--neutral-800); text-align: right; }
.receipt2 .sep { height: 1px; background: var(--color-border-subtle); margin: var(--space-12) 0; }

/* A paper the member says they have. Never an upload: the check means "yes I
 * have this", and the row deliberately offers nowhere to attach a file. */
.docs { display: flex; flex-direction: column; gap: 10px; margin-bottom: var(--space-16); }
.docrow {
  display: flex; align-items: center; gap: var(--space-12); width: 100%;
  padding: var(--space-12); cursor: pointer;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 12px;
  font: inherit; text-align: left;
}
.docrow.static { cursor: default; }
.docrow .ic { flex: 0 0 auto; display: grid; place-items: center; color: var(--aqua-600); }
.docrow .lb {
  flex: 1; font-weight: 600; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.docrow .bx {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--neutral-300); background: var(--color-surface-raised);
  display: grid; place-items: center;
}
.docrow.on .bx { border-color: var(--color-brand-fill); background: var(--color-brand-fill); color: #fff; }

/* One permission, one card. Two switches in a single box read as a settings
 * panel; separately they read as two decisions, which is what they are. */
.permrow {
  display: flex; align-items: center; gap: var(--space-16);
  padding: var(--space-12); margin-bottom: var(--space-8); cursor: pointer;
}
.permrow .lbl { flex: 1; min-width: 0; }
.permrow .lbl b {
  display: block; font-weight: 700; color: var(--color-text-primary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.permrow .lbl span {
  display: block; margin-top: var(--space-4); font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}

/* The send flow anchors its actions to the bottom of the phone, as the design
 * does: on a short step the primary button should be under the thumb, not
 * floating in the middle of an empty screen. Scoped to .flow rather than to
 * every .screen, because making .screen a flex column would stop margin
 * collapsing across the whole app. */
.screen.flow { display: flex; flex-direction: column; }
/* Anchored, not just pushed down (2026-09-02). margin-top:auto put them at the
 * bottom of a SHORT screen but let them scroll away on a long one (the papers
 * list), so the way forward was hidden exactly where there was most to read.
 * The fade lets content pass under them without a hard band across the glow. */
/* The screen's own bottom padding sits BELOW a sticky element, so a row could
 * still be seen under the bar. The flow screens hand that padding to the bar. */
.screen.flow { padding-bottom: 0; }
.screen.flow > .actions-bottom {
  position: sticky; bottom: 0; z-index: 3;
  margin-top: auto; padding: var(--space-16) 0 var(--space-24);
  background: linear-gradient(to top, var(--color-surface-base) 0%, var(--color-surface-base) 70%, rgba(253,250,246,0) 100%);
}

/* ----------------------------------------------------------- Mis casos (D) -- */

/* One case, as a card. The list summarises and the detail screen acts: every
 * control that changes a case now lives on the case, so this card carries
 * exactly one button and cannot grow a second column of decisions. */
.casecard {
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 16px;
  padding: var(--space-16); margin-bottom: var(--space-16);
  box-shadow: 0 4px 20px rgba(218,223,227,.32);
}
.casecard .hd { display: flex; align-items: center; justify-content: space-between; gap: var(--space-8); }
.casecard .when {
  flex: 0 0 auto; font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.casecard .ttl {
  display: block; margin: var(--space-12) 0 var(--space-4);
  font-family: var(--font-title); font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--title-md) * var(--scale)); line-height: var(--title-md-lh);
}
.casecard .org {
  font-weight: 600; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.casecard .org .lb { font-weight: 400; }
.casecard .rule { height: 1px; background: var(--color-border-subtle); margin: var(--space-12) 0; }
.ans { display: flex; align-items: center; gap: var(--space-8); }
.ans .ic { flex: 0 0 auto; display: grid; place-items: center; color: var(--color-brand-fill); }
.ans .k { font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh); }
.casecard .ans { margin-bottom: var(--space-8); }
.casecard .ans .ic { flex: 0 0 auto; display: grid; place-items: center; color: var(--color-brand-fill); }
.casecard .ans .k {
  font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.casecard .ans .v { font-weight: 700; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh); }
/* Clamped, not truncated with an ellipsis we wrote ourselves: the full sentence
 * is on the case, and a hand-written "..." lies about where the text ends. */
.casecard .body {
  font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; margin-bottom: var(--space-12);
}
.casecard .btn { margin: 0; }

/* The status chip. Tone carries the meaning, so it has to survive being read by
 * someone who cannot tell the colours apart: the words say it too. */
.chip-st {
  display: inline-flex; align-items: center; gap: var(--space-8);
  padding: var(--space-4) var(--space-8); border-radius: 8px;
  font-weight: 700; white-space: nowrap;
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
  background: var(--status-idle-bg); color: var(--status-idle);
}
.chip-st .ic { display: grid; place-items: center; }
.chip-st.waiting   { background: var(--status-waiting-bg);   color: var(--status-waiting); }
.chip-st.committed { background: var(--status-committed-bg); color: var(--status-committed); }
.chip-st.urgent    { background: var(--status-urgent-bg);    color: var(--status-urgent); }

/* The assigned attorney, on the case that has one. It replaces the "answer by"
 * row: once a human is on it, WHO has it matters more than WHEN. */
.att {
  display: flex; align-items: center; gap: var(--space-16);
  padding: var(--space-12); margin-bottom: var(--space-8);
  background: var(--color-surface-base); border: 1px solid var(--color-border-subtle); border-radius: 16px;
}
.att .avatar { flex: 0 0 auto; width: 48px; height: 48px; font-size: 16px; }
.att .n {
  font-family: var(--font-title); font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--title-sm) * var(--scale)); line-height: var(--title-sm-lh);
}
.att .r { font-weight: 500; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh); }

/* The case controls moved out of the list card and onto the case (2026-09-01),
 * where they are the screen's own actions rather than a card's footer, so they
 * stack full width like every other primary action in the app. */
.screen > .case-actions { display: flex; flex-direction: column; gap: var(--space-8); }
.screen > .case-actions .btn { width: 100%; }

/* The confirm sheet. Slides from the bottom because that is where the thumb is,
 * and it dims what is behind so the consequence is the only thing on screen. */
.sheet-wrap {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  background: rgba(41,40,36,.45);
  animation: fade .18s ease;
}
.sheet {
  width: 100%; max-width: 420px; box-sizing: border-box;
  background: var(--color-surface-raised); border-radius: 24px 24px 0 0;
  padding: var(--space-24) var(--pad) var(--space-32);
  animation: sheet-up .22s ease;
}
@keyframes sheet-up { from { transform: translateY(14px); } to { transform: none; } }
.sheet h2 {
  margin: 0 0 var(--space-8); font-family: var(--font-title); font-weight: 600;
  font-size: calc(var(--title-lg) * var(--scale)); line-height: var(--title-lg-lh);
  color: var(--color-text-primary);
}
.sheet p {
  margin: 0 0 var(--space-16); font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.sheet .note { margin-bottom: var(--space-24); text-align: left; }
.sheet .btn { margin: 0 0 var(--space-8); }

/* Her phone number, stated plainly with the way to change it right next to it.
 * A number she cannot correct in place is a number she stops trusting. */
.numrow {
  display: flex; align-items: center; gap: var(--space-12);
  padding: var(--space-12); margin-bottom: var(--space-8);
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 12px;
}
.numrow .ic { flex: 0 0 auto; display: grid; place-items: center; color: var(--color-brand-fill); }
.numrow .n {
  flex: 1; font-weight: 700; color: var(--color-text-primary); font-variant-numeric: tabular-nums;
  font-size: calc(var(--body-lg) * var(--scale)); line-height: var(--body-lg-lh);
}
.numrow .btn { margin: 0; flex: 0 0 auto; }

/* The question she was asked and the answer she gave, on the case. Labelled so
 * it is obvious which words are theirs and which are hers. */
.qa-k {
  font-weight: 700; color: var(--color-text-muted); margin-bottom: var(--space-8);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
  text-transform: none;
}
.qa-q {
  font-weight: 600; color: var(--neutral-800); margin-bottom: var(--space-4);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.qa-a {
  font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.card > .sep { height: 1px; background: var(--color-border-subtle); margin: var(--space-12) 0; }

/* A row that needs HER to act, not one telling her something. She should be able
 * to find it without reading: a human is waiting on this one. */
.att-row.needs-reply { background: var(--orange-50); }
.att-row.needs-reply .ic { color: var(--color-brand-fill); }
.tag-reply {
  display: inline-block; margin-left: var(--space-8);
  padding: 0 var(--space-8) 1px; border-radius: 38px;
  background: var(--color-brand-fill); color: #fff; white-space: nowrap;
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh); font-weight: 700;
}

/* A case waiting on HER, wherever it appears. The same treatment in the list,
 * on the Home rail and in Avisos, so "needs you" looks like one thing. */
/* A case waiting on her wears a badge like a notification, not an outline: the
 * orange border read as a selected option rather than as "this needs you". */
.card-slide.case-slide { position: relative; }
/* No separate dot badge: the chip IS the tag, and on the narrow rail card it
 * only truncated because the timestamp was competing for the same row. A case
 * that needs her gives the chip the whole row and drops the date, which is the
 * least useful thing on a card that is asking her to act. */
.card-slide.case-slide .chip.state { max-width: 100%; }
.chip.state.needs { background: var(--orange-50); color: var(--orange-600); }

/* What to cover, while she talks. Deliberately quiet: these are prompts, not
 * fields, and nothing here blocks her from finishing. They replaced a step that
 * asked the same four things one recording at a time. */
.prompts {
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle); border-radius: 16px;
  padding: var(--space-12) var(--space-16); margin-bottom: var(--space-16);
}
.prompts .ph {
  font-weight: 700; color: var(--color-text-secondary); margin-bottom: var(--space-8);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}
.prompts .pq {
  position: relative; padding-left: var(--space-16); margin-bottom: var(--space-4);
  font-weight: 600; color: var(--neutral-800);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.prompts .pq::before {
  content: ""; position: absolute; left: 0; top: 8px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--aqua-500);
}
.prompts .pq:last-child { margin-bottom: 0; }

/* ------------------------------------------------------------------ Home -- */

/* The band. Identity, greeting, who vouches for us, and one line of plan
 * readiness. Mi plan is already a tab, so Home carries how ready it is rather
 * than a fifth section competing with the four below. */
.band {
  background: linear-gradient(180deg, var(--orange-500) 0%, var(--orange-400) 100%);
  color: #fff; padding-bottom: var(--space-8);
}
.band .appbar.home, .band .endorse { background: transparent; border: 0; }
.band .wordmark, .band .ttl { color: #fff; }
.band .endorse { color: rgba(255,255,255,.85); margin: 0; padding: 0 var(--pad) var(--space-8); }
.band .megaphone { color: #fff; }
.band-plan {
  display: flex; align-items: center; gap: var(--space-12); width: 100%;
  margin: 0; padding: var(--space-12) var(--pad);
  background: rgba(255,255,255,.16); border: 0; border-top: 1px solid rgba(255,255,255,.22);
  font: inherit; color: #fff; cursor: pointer; text-align: left;
}
.band-plan .pl {
  flex: 1; font-weight: 700;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.band-plan .pb { display: flex; gap: 4px; flex: 0 0 auto; }
.band-plan .pb i { width: 18px; height: 6px; border-radius: 72px; background: rgba(255,255,255,.35); }
.band-plan .pb i.on { background: #fff; }
.band-plan .cv { flex: 0 0 auto; display: grid; place-items: center; opacity: .9; }

/* The one-line reading of her circle. Calm is a real state, not an empty one. */
.gstat {
  display: flex; align-items: center; gap: var(--space-8);
  margin: 0 0 var(--space-12); padding: var(--space-8) var(--space-12);
  border-radius: 12px; font-weight: 600;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.gstat.calm  { background: var(--status-committed-bg); color: var(--status-committed); }
.gstat.nag   { background: var(--status-waiting-bg);   color: var(--status-waiting); }
.gstat.alarm { background: var(--status-urgent-bg);    color: var(--status-urgent); }

/* One of her people, as a card she can tap to ask. */
[data-rail="gente"] { grid-auto-columns: 40%; gap: var(--space-8); }
.card-slide.person { text-align: center; padding: var(--space-12); }
.card-slide.person.can-ask { cursor: pointer; border-color: var(--orange-200); }
.person .pav {
  position: relative; display: grid; place-items: center;
  width: 48px; height: 48px; margin: 0 auto var(--space-8);
  border-radius: 50%; background: var(--color-brand-fill); color: #fff; font-weight: 700;
}
.person .ptag {
  position: absolute; top: -3px; right: -6px;
  min-width: 18px; height: 18px; padding: 0 3px; border-radius: 999px;
  display: grid; place-items: center; font-size: 10px; line-height: 1;
  background: var(--color-surface-raised); border: 1px solid var(--color-border-subtle);
}
.person .ptag.ok { background: var(--aqua-500); color: #fff; border-color: var(--aqua-500); }
.person .pn {
  font-family: var(--font-title); font-weight: 600; color: var(--color-text-primary);
  font-size: calc(var(--title-xs) * var(--scale)); line-height: var(--title-xs-lh);
}
.person .pf {
  margin-top: var(--space-4); font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}
/* "Última ubicación" is stated as a past fact with its own timestamp, never as
 * a live position, so a three-day-old pin cannot read as where she is now. */
.person .pf .loc { display: block; margin-top: var(--space-4); color: var(--color-text-muted); }
.person .pf .askq { color: var(--color-brand-fill); font-weight: 700; }
.askall { margin-top: var(--space-12); }

/* On the band, the wordmark and endorsement are white-on-orange. Both had
 * grey values set later in this file, which won on source order. */
.band .appbar.home .wordmark { color: rgba(255,255,255,.9); }
.band .appbar.home .ttl { color: #fff; }
.band .endorse { color: rgba(255,255,255,.9); font-weight: 600; }

/* How we can reach this person. For an SMS-only contact the line IS the
 * invitation, so it is a button: one tappable sentence instead of a warning, a
 * restatement and a button all saying the same thing. */
.reach {
  display: flex; align-items: center; gap: var(--space-8);
  padding: var(--space-8) 2px; width: 100%;
  font-weight: 600; color: var(--color-text-secondary); background: none; border: 0;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  text-align: left; font-family: inherit;
}
.reach.app { color: var(--aqua-700); }
/* Underlining text to mean "tappable" is a web habit, not an app one, so the
 * fact is stated and the action sits beside it as a button. */
.btn.xs { padding: 4px 12px; font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh); margin: 0; width: auto; }

/* The ack travels with the person, so Mi gente shows what Home shows. */
.ackside { display: flex; align-items: flex-start; gap: var(--space-8); flex: 0 0 auto; }
.ackside .ptag { position: static; }
.ackside .al {
  font-weight: 600; color: var(--color-text-secondary); text-align: right;
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}
.ackside .al .loc { display: block; color: var(--color-text-muted); }

/* The invite: an icon with its reason beneath it, sitting beside the fact. The
 * earlier version put "Para privacidad:" and a button on the same line as the
 * text, which wrapped and read as three unrelated things. */
.reach { align-items: flex-start; gap: var(--space-12); }
.reach .rt { flex: 1; display: flex; align-items: center; gap: var(--space-8); }
.invicon {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--space-4) var(--space-8); border: 1px solid var(--color-brand-fill); border-radius: 12px;
  background: var(--color-surface-raised); color: var(--color-brand-fill); cursor: pointer; font-family: inherit;
}
.invicon span {
  font-size: calc(11px * var(--scale)); line-height: 14px; font-weight: 700; white-space: nowrap;
}

/* The invitation under "SMS no es privado". A bare icon and a sentence, never a
 * box: a boxed button next to a warning read as two things competing rather
 * than as a statement and its remedy. */
.reach.sms { flex-direction: column; align-items: stretch; gap: var(--space-4); }
.reach.sms .rt { color: var(--amber-700); }
.invlink {
  display: flex; align-items: flex-start; gap: var(--space-8); width: 100%;
  padding: var(--space-4) 0 0; border: none; background: none; cursor: pointer;
  font-family: inherit; font-weight: 700; text-align: left;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
  color: var(--color-brand-text);
}
.invlink svg { flex: 0 0 auto; margin-top: 1px; }
.invlink:active { color: var(--orange-700); }

/* Which parts of the plan she has called finished. Without this the "3 de 4" on
 * Home is a number with nothing behind it. */
.tag-done {
  display: inline-flex; align-items: center; gap: 3px; margin-left: var(--space-8);
  padding: 0 var(--space-8) 1px; border-radius: 38px; vertical-align: 2px;
  background: var(--status-committed-bg); color: var(--status-committed);
  font-family: var(--font-body); font-weight: 700;
  font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}

/* "Pregúntales a todos" as a label plus the message itself on a pill, rather
 * than a full-width block button. The block read as a primary action competing
 * with the cards above it; this reads as what it is, a shortcut. */
.askall {
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: var(--space-8); margin-top: var(--space-12);
}
.askall .lb {
  font-weight: 600; color: var(--color-text-secondary);
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.pill-ask {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px var(--space-12); border-radius: 999px;
  background: var(--orange-50); border: 1px solid var(--color-brand-fill); color: var(--color-brand-fill);
  font-family: inherit; font-weight: 700; cursor: pointer;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.pill-ask:active { transform: scale(.98); }
/* Asked, waiting: a sent marker rather than the hourglass an unconfirmed
 * person wears, so "I messaged them" is not confused with "they never joined". */
.person .ptag.sent { background: var(--color-brand-fill); color: #fff; border-color: var(--color-brand-fill); }

/* An illustrated face until a real photo exists. The slot takes an <img> the
 * moment one does, so nothing changes but the source. */
.face { display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.person .pav { background: none; padding: 0; overflow: visible; }
.avatar.photo { background: none; padding: 0; overflow: hidden; }

/* The badge Doug asked for, Slack-style. It fits now because a case that needs
 * her gives the chip the row and drops the date, so the corner is free. */
.badge-dot {
  position: absolute; top: 10px; right: 10px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 3px var(--color-surface-raised);
  z-index: 2;
}

/* One page per person. Roles, the executor choice and "¿Todo bien?" live here
 * now, which takes four controls off every card in the list, and means tapping
 * a face opens a page instead of firing a message. */
.person-hd { text-align: center; margin-bottom: var(--space-16); }
.person-hd .pav.lg { display: block; width: 96px; height: 96px; margin: 0 auto var(--space-12); }
.person-hd h1 { margin: 0; }
.person-hd p { margin: 2px 0 0; }
.personcard { cursor: pointer; margin-bottom: 10px; }
.personcard:active { transform: scale(.995); }
.prow { display: flex; flex-wrap: wrap; gap: var(--space-8); margin: var(--space-8) 0 0; }
.rolechip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 0 var(--space-8) 1px; border-radius: 38px;
  background: var(--orange-50); color: var(--orange-600);
  font-weight: 700; font-size: calc(var(--body-sm) * var(--scale)); line-height: var(--body-sm-lh);
}
.rolechip.alb { background: var(--aqua-50); color: var(--aqua-700); }

/* Adding a face to a contact. A photo of a PERSON, which is not the same thing
 * as a photo of a document: we never take her papers, and this never leaves
 * the phone. */
.photopick { display: flex; align-items: center; gap: var(--space-16); margin-bottom: var(--space-16); }
.photopick .pav.lg { display: block; width: 88px; height: 88px; flex: 0 0 auto; }
.photopick label { margin: 0; cursor: pointer; }

/* The + sits on the picture, bottom right, the way every app does it. The whole
 * avatar is the label, so tapping the face opens the picker. */
.photopick { display: block; text-align: center; margin-bottom: var(--space-16); }
.photopick .pav.lg {
  position: relative; display: inline-block; width: 96px; height: 96px; cursor: pointer;
}
.photopick .plus {
  position: absolute; right: -2px; bottom: -2px;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--color-brand-fill); color: #fff; border: 3px solid var(--color-surface-base);
}

/* ------------------------------------------------------ Home band (dark) -- */

/* Dark behind the faces, the way WhatsApp does it: the portraits carry the
 * colour and the app's warmth resumes the moment the band ends. Deliberately a
 * warm near-black rather than pure black, because true black reads
 * institutional, and institutional is the register we are avoiding. */
.band {
  background: #171614;
  color: #fff;
  padding-bottom: var(--space-12);
}
/* Keep position:relative: the megaphone is absolutely positioned against the
 * app bar, and making it static dropped the megaphone out of the band entirely. */
.band .appbar.home { background: transparent; border: 0; padding-bottom: 0; padding-right: 56px; }
.band .appbar.home .slot { flex: 1 1 auto; min-width: 0; display: block; }
.band .appbar.home .wordmark {
  display: block; color: #fff; font-size: calc(19px * var(--scale)); line-height: 24px;
  font-weight: 600; padding-left: 0;
}
/* Who vouches for us reads with the name, not as a row of its own. */
.band .endorse {
  display: block; margin: 1px 0 0; padding: 0; background: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: rgba(255,255,255,.72); font-weight: 600;
  font-size: calc(11.5px * var(--scale)); line-height: 15px;
}
.band .megaphone { color: #fff; }

/* Story circles. A ring for state, a badge for the detail: the grammar people
 * already know from every other app on the phone. Everything else about a
 * person is one tap away on their page. */
.storyrow {
  display: flex; gap: var(--space-16); overflow-x: auto;
  padding: var(--space-8) var(--pad) var(--space-4);
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.storyrow::-webkit-scrollbar { display: none; }
.story {
  flex: 0 0 auto; width: 68px; background: none; border: 0; padding: 0;
  font: inherit; cursor: pointer; text-align: center;
}
.sring {
  position: relative; display: block; width: 68px; height: 68px; margin: 0 auto 5px;
  border-radius: 50%; padding: 3px; box-sizing: border-box;
  background: rgba(255,255,255,.18);
}
.sring .face { width: 100%; height: 100%; }
.sring.ok   { background: var(--aqua-500); }
.sring.sent { background: var(--color-brand-fill); }
.sring.wait { background: rgba(255,255,255,.32); }
.sring.help { background: var(--red-500); }
.sbadge {
  position: absolute; right: -1px; bottom: -1px;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; border: 2px solid #171614;
}
.sbadge.ok { background: var(--aqua-600); }
.sbadge.sent { background: var(--color-brand-fill); }
.sbadge.wait { background: var(--neutral-500); }
.sbadge.help { background: var(--red-600); }
/* The last bubble in the row adds a person. Same size and rhythm as a face, so
 * it reads as the end of the row rather than as a control bolted onto it. */
.story.addp .sring {
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.14);
  border: 1.5px dashed rgba(255,255,255,.55); color: #fff;
}
.story.addp:active .sring { background: rgba(255,255,255,.26); }
.sname {
  display: block; color: #fff; font-weight: 600;
  font-size: calc(11.5px * var(--scale)); line-height: 15px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gente-sec { margin-top: var(--space-12); }

/* The circle's state, inside the dark band with the faces it describes. Light
 * on dark, so it is a caption under the row rather than a card competing with
 * the carousels below it. */
.bandstat {
  display: flex; align-items: center; gap: var(--space-8);
  margin: 2px var(--pad) 0; padding: var(--space-8) var(--space-12);
  border-radius: 12px; background: rgba(255,255,255,.10); color: #fff;
  font-size: calc(var(--body-md) * var(--scale)); line-height: var(--body-md-lh);
}
.bandstat svg { flex: 0 0 auto; color: var(--aqua-300); }
.bandstat.alarm { background: rgba(219,90,87,.24); }
.bandstat.alarm svg { color: var(--red-300); }

/* Mi plan, pinned above the tab bar rather than scrolling away. On a phone the
 * bottom is the reachable place, and this is the one thing Home should keep
 * offering however far down she is. Docked WITH the tabs, not offset from them
 * by a hard number: the tab bar grows with the text-size setting, so any fixed
 * offset would be wrong for whoever needs the large type most. */
.dock { position: sticky; bottom: 0; z-index: 5; }
.dock .tabbar { position: static; }
.band-plan.pinned {
  width: 100%; border: 0; border-top: 1px solid var(--color-border-subtle);
  background: var(--color-brand-fill); color: #fff;
  padding: var(--space-12) var(--pad);
}
.band-plan.pinned .pb i { background: rgba(255,255,255,.4); }
.band-plan.pinned .pb i.on { background: #fff; }

/* Airplane left, identity centred, megaphone right. The airplane asks everyone
 * "¿Todo bien?", which is frequent enough to belong in the bar, and it still
 * goes through the confirm sheet so a stray tap sends nothing. */
.band .appbar.home { padding-left: var(--space-8); padding-right: var(--space-8); }
.band .appbar.home .slot { flex: 1 1 auto; min-width: 0; display: block; text-align: center; }
.askicon {
  flex: 0 0 auto; width: 52px; background: none; border: 0; padding: 4px 0;
  color: #fff; font: inherit; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
}
.askicon .lb {
  font-size: calc(9.5px * var(--scale)); line-height: 12px; font-weight: 700;
  color: rgba(255,255,255,.8); white-space: nowrap;
}
.askicon.ghost { visibility: hidden; }
/* The megaphone is absolutely positioned; the airplane balances it so the
 * wordmark sits in the true centre rather than in the space left over. */
.band .megaphone { right: 12px; }

/* A rights card that has a film says so, with the play area the mockup asks
 * for. Cards without a video keep their old shape: a play button over a
 * scenario we have no film for is a promise we cannot keep. */
.card-slide.right.hasvid { display: flex; flex-direction: column; gap: var(--space-8); }
.card-slide.right .rt-hd { display: flex; align-items: center; gap: var(--space-12); }
/* The film is the card. It leads at a real 16:9 rather than sitting under the
 * text as a thumbnail, because the video IS the content here and the title is
 * the caption. */
.vidbox {
  display: grid; place-items: center; width: 100%; align-self: stretch;
  aspect-ratio: 16 / 9; border-radius: 12px; box-sizing: border-box;
  background: linear-gradient(135deg, var(--neutral-800), var(--neutral-900));
}
.card-slide.right.hasvid { flex-direction: column-reverse; }
.card-slide.right .rt-hd { align-items: flex-start; }
/* Same shape, honest label. Every scenario will have a film eventually, and a
 * card that changes shape when one lands is a card that never settles. */
.vidbox.soon {
  background: var(--color-surface-base); border: 1px dashed var(--color-border-subtle); color: var(--color-text-muted);
  font-weight: 600; font-size: calc(var(--body-sm) * var(--scale));
}
.playbig {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.92); color: var(--neutral-900);
}
[data-rail="rights"] { grid-auto-columns: 82%; gap: var(--space-12); }

/* The player itself, on the scenario's own screen. */
.vidwrap {
  position: relative; width: 100%; padding-top: 56.25%;
  border-radius: 16px; overflow: hidden; background: var(--neutral-900);
  margin-bottom: var(--space-8);
}
.vidwrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* The still stands in until she asks to play, so a scenario costs one small
 * image instead of an embedded player sitting there loading. */
.vidbox { background-size: cover; background-position: center; }
.vidposter {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0; padding: 0;
  background-size: cover; background-position: center; cursor: pointer;
  display: grid; place-items: center;
}
