/* components.css — frontend.md §5's 11 components (F07), plus the app
   bar and tab bar (F08) -- build-prompt v2 §2's own file-layout note
   assigns app-bar/tab-bar to this file, even though the roadmap task
   that builds them is F08, not F07.
   Extracted from theme.html's COMPONENTS section, component by
   component -- not copied as one contiguous block, since theme.html
   interleaves these with §7 screen chrome (balance card, quick actions,
   day header, definition rows, result screen) neither feature owns.
   theme.html's own section comments are kept as the paper trail back to
   the reference. */

/* Buttons (§5.1) */
/* Shared press-transition, reused by .btn/.pin-dot/.pin-key below. */
.btn, .pin-dot, .pin-key {
  transition: transform var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  min-height:52px; padding:0 20px; border-radius:var(--radius-md);
  font-size:16px; font-weight:600; width:100%;
}
.btn:active { transform: scale(.98); }
.btn[disabled] { opacity:.45; pointer-events:none; }
.btn--primary     { background:var(--brand); color:var(--on-brand); }
.btn--primary:hover{ background:var(--brand-hover); }
.btn--secondary   { background:var(--surface); color:var(--text);
                    border:1px solid var(--border-strong); min-height:48px; }
.btn--ghost       { background:transparent; color:var(--brand); min-height:44px;
                    width:auto; padding:0 8px; }
.btn--destructive { background:var(--danger-bg); color:var(--danger);
                    border:1px solid var(--danger); }
.btn--auto { width:auto; padding-inline:24px; }
.btn__spinner {
  width:16px; height:16px; border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%; animation: spin .7s linear infinite; flex:none;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Amount (§5.2) */
.amount { font-variant-numeric: tabular-nums; font-feature-settings:"tnum" 1;
          white-space:nowrap; font-weight:600; }
.amount__cur { font-size:.62em; font-weight:600; opacity:.70; margin-inline-end:.25em; }
.amount__dec { font-size:.62em; opacity:.65; }
.amount--hero { font-size:34px; line-height:1.05; font-weight:700; min-inline-size:7ch;
                display:inline-block; }
.amount--lg { font-size:22px; line-height:1.2; }
.amount--md { font-size:17px; line-height:1.3; }
.amount--sm { font-size:15px; line-height:1.3; }
.amount[data-direction="credit"] { color: var(--credit); }
.amount[data-direction="debit"]  { color: var(--debit); }

/* Amount input (§7.5) -- F20. The one hero-sized editable amount field. */
.amount-input { display:flex; align-items:baseline; justify-content:center; gap:8px; margin:var(--space-6) 0; }
.amount-input__cur { font-size:15px; color:var(--text-muted); font-weight:600; }
.amount-input__field { border:none; background:none; text-align:center; width:auto; max-width:12ch;
  font-size:34px; font-weight:700; color:var(--text); font-variant-numeric:tabular-nums; }
.amount-input__field:focus { outline:none; box-shadow:0 2px 0 0 var(--brand); }
.amount[data-direction="credit"] .amount__int::before { content:"+"; }
.amount[data-direction="debit"]  .amount__int::before { content:"\2212"; }

/* Destination rows (§7.5, F22 -- 1..n destinations, capped at 5 fixed
   rows; see f22-transfer/requirements.md). */
.transfer-rows { display:flex; flex-direction:column; gap:var(--space-4); margin:var(--space-3) 0; }
.transfer-row { display:flex; flex-direction:column; gap:var(--space-2); }
.transfer-row__payoff { display:flex; align-items:center; justify-content:space-between;
  gap:var(--space-2); font-size:13px; color:var(--text-muted); }

/* Switch (§7.6, F25) -- a role="switch" button, not a checkbox input. */
.switch { width:44px; height:26px; border-radius:var(--radius-full); background:var(--border-strong);
  padding:2px; flex-shrink:0; }
.switch[aria-checked="true"] { background:var(--brand); }
.switch__thumb { display:block; width:22px; height:22px; border-radius:50%; background:var(--surface);
  transition:transform var(--dur-fast) var(--ease); }
.switch[aria-checked="true"] .switch__thumb { transform:translateX(18px); }

/* Segmented control (§7.6, F25) -- no prior component to reuse. */
.segmented { display:flex; background:var(--surface-2); border-radius:var(--radius-md); padding:2px; gap:2px; }
.segmented__option { flex:1; min-height:36px; border-radius:calc(var(--radius-md) - 2px);
  font-size:14px; font-weight:600; color:var(--text-muted); }
.segmented__option[aria-checked="true"] { background:var(--surface); color:var(--text); }

/* Shared 44px circular icon-button base -- eye toggle, app-bar icon
   buttons, banner dismiss. Each below keeps only what differs. */
.eye, .icon-btn, .banner__dismiss {
  width:44px; height:44px; display:flex; align-items:center; justify-content:center;
  border-radius:var(--radius-full);
}

/* Hidden-balance toggle (§5.3) */
.eye { color:inherit; }
.eye:active { background:rgba(255,255,255,.16); }

/* Status chip (§5.4) */
.chip {
  display:inline-block; padding:4px 10px; border-radius:var(--radius-full);
  font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  background:var(--surface-2); color:var(--text-muted); white-space:nowrap;
}
.chip--active  { background:var(--ok-bg);     color:var(--ok); }
.chip--dormant { background:var(--warn-bg);   color:var(--warn); }
.chip--blocked { background:var(--danger-bg); color:var(--danger); }
.chip--closed  { background:var(--surface-2); color:var(--text-muted); }

/* Grouped list + rows (§5.5) */
.list {
  background:var(--surface); border:1px solid var(--border);
  border-radius:var(--radius-lg); overflow:hidden;
}
.row {
  display:flex; align-items:center; gap:12px; min-height:64px;
  padding:12px var(--space-4); position:relative; width:100%; text-align:left;
  background:none; transition: background-color var(--dur-fast) var(--ease);
  color:inherit; text-decoration:none;
  content-visibility:auto; contain-intrinsic-size:auto 64px;
}
.row + .row::before {
  content:""; position:absolute; top:0; left:var(--space-4); right:0;
  height:1px; background:var(--border);
}
.row:active { background:var(--surface-2); }
.row__main { flex:1 1 auto; min-width:0; color:inherit; text-decoration:none; }
.row__end  { flex:none; text-align:right; display:flex; flex-direction:column;
             align-items:flex-end; gap:4px; }
.row-actions { display:flex; gap:8px; }
.row__title {
  font-size:15px; line-height:1.45; white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis;
}
.row__meta { font-size:13px; line-height:1.4; color:var(--text-muted);
             white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.row--unavailable { opacity:.6; }

/* PIN pad (§5.6) */
.pin-dots { display:flex; gap:16px; justify-content:center; padding:20px 0; }
.pin-dot {
  width:14px; height:14px; border-radius:50%;
  border:2px solid var(--border-strong); background:transparent;
}
.pin-dot[data-filled="true"] {
  background:var(--brand); border-color:var(--brand); transform:scale(1.08);
}
.pin-dots[data-error="true"] { animation: shake 320ms var(--ease); }
@keyframes shake {
  0%,100%{transform:translateX(0)} 20%{transform:translateX(-8px)}
  40%{transform:translateX(8px)}   60%{transform:translateX(-6px)}
  80%{transform:translateX(4px)}
}
.pin-pad { display:grid; grid-template-columns:repeat(3,68px); gap:16px;
           justify-content:center; }
.pin-key {
  width:68px; height:68px; border-radius:var(--radius-md);
  background:var(--surface); border:1px solid var(--border);
  font-size:24px; font-weight:500; color:var(--text);
  display:flex; align-items:center; justify-content:center;
}
.pin-key:active { background:var(--surface-2); transform:scale(.96); }
.pin-key--blank { visibility:hidden; }
.pin-key:disabled { opacity:.45; pointer-events:none; }
.pin-text-entry { display:none; }
@media (min-width: 1200px) {
  /* A touch keypad is the wrong control with a mouse and keyboard --
     desktop gets a single masked field instead (frontend.md has no
     precedent for this pattern; written for this breakpoint). */
  .pin-dots, .pin-pad { display:none; }
  .pin-text-entry { display:block; max-width:240px; margin:20px auto; }
  .pin-text-entry__input { text-align:center; letter-spacing:10px; font-size:20px; }
  .pin-dots[data-error="true"] ~ .pin-text-entry { animation: shake 320ms var(--ease); }
}

/* OTP (§5.7) */
.otp { display:flex; gap:8px; justify-content:center; }
.otp input {
  width:48px; height:56px; text-align:center; font-size:22px; font-weight:600;
  border:1px solid var(--border-strong); border-radius:var(--radius-md);
  background:var(--surface); color:var(--text);
}
.otp input:focus { outline:none; border:2px solid var(--brand); }

/* Bottom sheet (§5.8) */
.sheet-backdrop {
  position:fixed; inset:0; background:rgba(15,23,42,.5);
  opacity:0; pointer-events:none; transition:opacity var(--dur) var(--ease);
}
.sheet-backdrop[data-open="true"] { opacity:1; pointer-events:auto; }
.sheet {
  position:fixed; left:0; right:0; bottom:0; z-index:1;
  background:var(--surface); border-radius:var(--radius-xl) var(--radius-xl) 0 0;
  box-shadow:var(--shadow-sheet); padding:12px var(--space-4) var(--space-6);
  transform:translateY(100%); transition:transform var(--dur-slow) var(--ease);
  max-height:85dvh; overflow:auto;
}
.sheet[data-open="true"] { transform:translateY(0); }
.sheet__handle {
  width:36px; height:4px; border-radius:var(--radius-full);
  background:var(--border-strong); margin:0 auto 16px;
}
.sheet__title { margin:0 0 12px; }
@media (min-width: 768px) {
  .sheet {
    left:50%; right:auto; bottom:50%; top:auto;
    transform:translate(-50%,50%) scale(.96); opacity:0;
    width:100%; max-width:420px; border-radius:var(--radius-lg);
  }
  .sheet[data-open="true"] { transform:translate(-50%,50%) scale(1); opacity:1; }
}

/* Skeleton (§5.9) */
.skeleton {
  background: linear-gradient(90deg,
    var(--surface-2) 25%,
    color-mix(in oklab, var(--surface-2), var(--text) 6%) 37%,
    var(--surface-2) 63%);
  background-size:400% 100%; animation: shimmer 1.4s ease infinite;
  border-radius:var(--radius-sm);
}
@keyframes shimmer { 0%{background-position:100% 0} 100%{background-position:0 0} }

/* Empty state (§5.10) */
.empty { text-align:center; padding:48px 24px; }
.empty svg { color:var(--text-subtle); margin-bottom:12px; }
.empty__title { font-size:17px; font-weight:600; margin:0 0 4px; }
.empty__body, .result__body { font-size:15px; color:var(--text-muted); margin:0 auto 20px; max-width:34ch; }

/* Balance card (§7.2) -- the one large brand surface. F15. */
.balance-card { position:relative; overflow:hidden; color:var(--on-brand);
  border-radius:var(--radius-xl); padding:var(--space-5);
  background:linear-gradient(135deg, var(--brand) 0%, color-mix(in oklab, var(--brand), black 22%) 100%); }
.balance-card::after { content:""; position:absolute; top:-40%; right:-20%; width:260px; height:260px;
  border-radius:50%; background:radial-gradient(circle, rgba(255,255,255,.40), transparent 68%); pointer-events:none; }
.balance-card__head { display:flex; align-items:center; justify-content:space-between; }
.balance-card__label { font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; opacity:.85; }
.balance-card .amount--hero { display:block; margin-top:6px; }
.balance-card__loans, .balance-card__error { margin-top:18px; opacity:.85; }
.balance-card__loans { display:flex; justify-content:space-between; align-items:baseline; font-size:15px; }
.balance-card .eye { margin:-10px -10px -10px 0; }

/* Quick actions (§7.2, D49). --3-up fixes the column count (e.g. a
   flag-hidden tile leaves no gap); --lg enlarges the tile (dashboard only). F15. */
.quick { display:grid; grid-template-columns:repeat(5,1fr); gap:8px; }
.quick--3-up { grid-template-columns:repeat(3,1fr); gap:16px 8px; }
.quick__item { display:flex; flex-direction:column; align-items:center; gap:6px; padding:4px 0; color:var(--text); }
.quick__icon { width:56px; height:56px; border-radius:var(--radius-md); background:var(--surface-2); color:var(--brand);
  display:flex; align-items:center; justify-content:center; transition:transform var(--dur-fast) var(--ease); }
.quick--lg .quick__icon { width:76px; height:76px; border-radius:var(--radius-lg); }
.quick--lg .quick__label { font-size:14px; }
.quick__item:active .quick__icon { transform:scale(.94); }
.quick__label { font-size:13px; font-weight:500; }

/* Result screen (§7.5) */
.result { text-align:center; padding:32px 24px; }
.result svg { margin-bottom:16px; color:var(--brand); }
.result__title { margin:0 0 6px; }
.result__actions { display:flex; flex-direction:column; gap:12px; }
.result--success svg { color:var(--ok); }
.result--warn svg { color:var(--warn); }
.result--danger svg { color:var(--danger); }

/* Processing state (§6.8); layout is in screens.css. */
.processing-screen__spinner { width:32px; height:32px; border-width:3px; color:var(--brand); margin-bottom:16px; }

/* Inline banner (§5.11) */
.banner {
  display:flex; gap:12px; align-items:flex-start;
  padding:12px; border-radius:var(--radius-md);
  border:1px solid var(--border); background:var(--surface-2);
  font-size:15px; line-height:1.45;
}
.banner--info   { background:var(--info-bg);   border-color:color-mix(in oklab,var(--brand),transparent 70%); }
.banner--warn   { background:var(--warn-bg);   border-color:color-mix(in oklab,var(--warn),transparent 70%); color:var(--warn); }
.banner--danger { background:var(--danger-bg); border-color:color-mix(in oklab,var(--danger),transparent 70%); color:var(--danger); }
.banner svg { flex:none; margin-top:2px; }
.banner__dismiss { flex:none; margin:-10px -10px -10px auto; color:inherit; }
.banner__dismiss:active { background:rgba(0,0,0,.08); }

/* App bar (§4.2) + tab bar (§4.3) -- F08 */
.app-bar {
  height:56px; display:flex; align-items:center; gap:8px; padding:0 var(--space-4);
  background:var(--surface); border-bottom:1px solid var(--border); flex:none;
  padding-top: env(safe-area-inset-top);
}
.app-bar__title { flex:1 1 auto; font-size:17px; font-weight:600;
                  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.app-bar__title--center { text-align:center; }
.icon-btn { flex:none; color:var(--text-muted); }
.icon-btn:active { background:var(--surface-2); }
.app-bar__spacer { width:44px; flex:none; }
/* Refresh has no gesture equivalent on a mouse -- shown only where pull-
   to-refresh isn't reachable (frontend.md §12). F15. */
.app-bar__refresh { display:none; }
@media (min-width: 1200px) { .app-bar__refresh { display:flex; } }
/* Settings menu (D62) -- a native <details>, .list/.row (§5.5) reused
   for the popped-out panel so it needs no styling of its own. */
.app-bar__menu { position:relative; }
.app-bar__menu > summary { list-style:none; cursor:pointer; }
.app-bar__menu > summary::-webkit-details-marker { display:none; }
.app-bar__menu .list { position:absolute; top:100%; right:0; margin-top:8px; min-width:180px; box-shadow:var(--shadow-dialog); }

.tab-bar {
  height:56px; display:grid; grid-template-columns:repeat(4,1fr);
  background:var(--surface); border-top:1px solid var(--border); flex:none;
  padding-bottom: env(safe-area-inset-bottom);
}
.tab-bar .tab-bar__sidebar-only { display:none; }
.tab {
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2px; color:var(--text-muted); font-size:10px; font-weight:600;
  letter-spacing:.04em; text-transform:uppercase;
}
.tab[aria-current="page"], .app-bar__profile[aria-current="page"] { color:var(--brand); }

/* Responsive shell transformation (frontend.md §12) -- written from the
   spec's prose, not theme.html: its demo explicitly excludes tablet/
   desktop layouts ("Not shown here ... the tablet and desktop layouts"). */
@media (min-width: 768px) {
  .tab-bar {
    position:fixed; top:0; left:0; bottom:0; height:auto; width:80px;
    display:flex; flex-direction:column; padding-top:24px;
    border-top:0; border-right:1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .tab { flex-direction:column; padding:12px 0; font-size:10px; }
  .app-bar, .content { margin-left:80px; }
}
@media (min-width: 1200px) {
  .tab-bar { width:240px; align-items:flex-start; padding:24px 16px; }
  .tab {
    flex-direction:row; justify-content:flex-start; gap:12px; font-size:13px;
    text-transform:none; letter-spacing:normal; font-weight:500; width:100%;
    padding:10px 12px; border-radius:var(--radius-md);
  }
  .tab[aria-current="page"] { background:var(--brand-subtle); }
  .app-bar, .content { margin-left:240px; }
  .tab-bar .tab-bar__sidebar-only { display:block; width:100%; }
  .tab-bar__identity { margin-top:auto; padding-top:var(--space-3); border-top:1px solid var(--border); }
}
/* F26: sidebar-only mark + identity (>=1200px, .tab-bar__sidebar-only). */
.sidebar-logo {
  width:32px; height:32px; border-radius:8px; margin-bottom:var(--space-4);
  background:var(--brand); color:var(--on-brand);
  display:flex; align-items:center; justify-content:center;
  font-weight:800; font-size:14px;
}
.tab-bar__identity { display:flex; flex-direction:column; gap:var(--space-2); width:100%; }

/* Money-form card width (§12, F26) -- scoped to .money-form only, not a
   blanket .content rule: .dashboard is shared by several non-grid
   screens (accounts_list/loans_list/profile/transact) whose interaction
   with the dashboard screen's own 2-/3-col grid rule wasn't something
   this feature could visually verify -- see requirements.md's own note. */
@media (min-width: 768px) { .money-form { max-width:720px; margin-inline:auto; } }
@media (min-width: 1200px) { .money-form { max-width:560px; } }

/* D81: review/PIN-confirm amount, PIN heading, Balance Enquiry result header. */
.money-form__amount, .money-form__pin-title, .balance-result { text-align: center; }

/* Master-detail (§12, F26) -- Accounts/Loans/Statements, >=1200px only;
   below that the master pane's list is always fetched (server can't
   know the viewport) but never shown, same "server always renders both
   variants, CSS picks" pattern F15's hide-balance markup uses. */
.row--selected { background:var(--surface-2); }
.master-detail__list { display:none; }
@media (min-width: 1200px) {
  .master-detail { display:flex; align-items:flex-start; gap:var(--space-6); }
  .master-detail__list { display:block; flex:0 0 360px; }
  .master-detail__detail { flex:1 1 auto; }
}
