/* ==========================================================================
   Online banking — design system
   Generic placeholder branding only: no third-party bank names, logos or
   product marks anywhere in this file or the markup it styles.
   ========================================================================== */

/* The body already asked for Inter but nothing ever loaded it, so every machine
   without it fell back to Segoe UI. This fetches it. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Montserrat:wght@600;700;800&family=Source+Sans+3:wght@400;500;600;700&display=swap');

/* --------------------------------------------------------------------------
   Palette: deep navy on cool white, with elevation carrying the separation
   between a card and the page behind it.

   This reverses three choices made on 2026-08-27 (no shadows, 4px radii, no
   pure white). That was a deliberate instruction on 2026-09-01, not drift: the
   reference was a retail banking app built on Material surfaces, and the user
   chose the full restyle over a structure-only pass after the trade-off was put
   to him. This is not a git repository, so the previous palette is not
   recoverable from history — the values are written out in the 2026-08-27
   entry of the design memory if they are ever wanted back.

   Every text pair is still checked against WCAG 2.1 rather than picked by eye.
   Moving off cream onto white raised every ratio, so nothing regressed.
   -------------------------------------------------------------------------- */
:root {
  /* Structure. The "blue" names are kept because the whole stylesheet and the
     back office reference them; only the values moved to navy. */
  --brand-blue-primary: #12233A;
  --brand-blue-hover: #1C3A5E;
  --brand-navy-hero: #12233A;
  --brand-navy-dark: #0B1626;

  /* Surfaces: cool grey page, white cards sitting on it, tint for recessed
     areas. Sections read as cards lifted off the page, not as bands in it. */
  --bg-app: #F5F6F8;
  --bg-card: #FFFFFF;
  --bg-muted: #EEF1F5;

  /* Text — 15.8:1, 6.08:1 and 5.64:1 on the white card */
  --text-primary: #12233A;
  --text-secondary: #55606E;
  --text-muted: #5C6672;
  --text-on-dark: #FFFFFF;

  /* Indicators. Each stays legible as text on white: 6.1:1, 7.2:1, 6.3:1 */
  --accent-green: #1B6B4A;
  --accent-red: #A32B22;
  --accent-amber: #8A5A10;

  /* Lines. --silver is decorative only (2.67:1 on white) and must never carry
     text or bound a control; --silver-strong (4.80:1) is what borders inputs
     and buttons, where WCAG 1.4.11 wants 3:1. */
  --silver: #94A3B8;
  --silver-strong: #64748B;
  --border-soft: #E3E8EF;
  --border-strong: #CBD5E1;

  /* Elevation. Two stacked shadows rather than one: a tight contact shadow that
     seats the edge, and a wider ambient one that gives the lift. A single large
     blur is the thing that reads as a generated template. --shadow-hover is an
     elevation change only — no transform, because a button sliding toward the
     cursor was called out by name and is not coming back. */
  --shadow-card: 0 1px 2px rgba(18, 35, 58, 0.06), 0 2px 8px rgba(18, 35, 58, 0.07);
  --shadow-hover: 0 2px 4px rgba(18, 35, 58, 0.08), 0 6px 16px rgba(18, 35, 58, 0.10);
  --shadow-float: 0 8px 28px rgba(18, 35, 58, 0.16);

  /* Shape. Rounded, in the retail-app register rather than the institutional
     one: controls at 6, cards at 10, hero surfaces at 16. */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sidebar-w: 232px;
  /* Width of the customer-area content column, gutters included. 1280 sits in
     the 1200-1440 band the retail banking layouts settle on, and leaves the
     dashboard's reading column near the top of the comfortable range once the
     side rail is taken off it. */
  --shell-max: 1280px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'Inter', 'Segoe UI', 'Open Sans', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-primary);
  background: var(--bg-app);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--brand-blue-hover); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Restrained institutional: headings are smaller and tighter than the previous
   set, and carry their weight through tracking rather than size. The gap
   between a heading and body text is weight and colour, not scale. */
h1, h2, h3, h4 {
  margin: 0 0 12px 0;
  line-height: 1.3;
  color: var(--text-primary);
  letter-spacing: -0.015em;
}
h1 { font-size: 23px; font-weight: 700; line-height: 1.2; letter-spacing: -0.022em; }
h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.018em; }
h3 { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }

/* Money lines up in a column. Proportional digits are different widths, so a
   stack of balances never aligns; tabular ones do. */
.num, .acct-hero-bal, .acct-bal, .tile-value, .bal, td.num, th.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

p { margin: 0 0 12px 0; }
small, .muted { font-size: 12px; color: var(--text-secondary); }
.muted { display: block; max-width: 78ch; }

/* The browser hides [hidden] with a rule on the element type, which any class
   that sets display outranks - so a flex container carrying the attribute
   stayed on screen. That is how the QR scanner appeared over the first step of
   the transfer flow before anyone had asked for it. The attribute has to win,
   because every page here uses it as the on/off switch for a panel. */
[hidden] { display: none !important; }

/* Shell pages ship their content as bare markup and JS moves it into #main.
   Painting that half-built state first showed a flash of stray headings and
   empty tables, so it stays hidden until the shell says it is assembled.
   Standalone pages carry a body class and are never hidden. */
body:not([class]):not(.shell-ready) { visibility: hidden; }

/* ---------------------------------------------------------------- shell -- */

#sidebar {
  position: fixed;
  left: 0; top: 0; bottom: 0;
  width: var(--sidebar-w);
  padding: 20px 14px;
  background: var(--bg-card);
  border-right: 1px solid var(--border-soft);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.brand { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
.brand-mark {
  width: 32px; height: 32px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, var(--brand-navy-hero) 0%, var(--brand-blue-primary) 100%);
  display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: 13px; letter-spacing: .5px;
  flex: none;
}
.brand-name { font-size: 14px; font-weight: 700; color: var(--text-primary); line-height: 1.2; }
.brand-sub { font-size: 11px; color: var(--text-muted); }

#sidebar nav { display: flex; flex-direction: column; gap: 2px; }
#sidebar nav a {
  display: block;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-weight: 500;
  font-size: 13.5px;
  text-decoration: none;
  transition: background 150ms ease, color 150ms ease;
}
#sidebar nav a:hover { background: var(--bg-muted); color: var(--text-primary); text-decoration: none; }
#sidebar nav a.active {
  background: var(--brand-blue-primary);
  color: var(--text-on-dark);
  font-weight: 600;
}

#sidebar .who {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
  font-size: 12px;
  color: var(--text-secondary);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#sidebar .who select { width: 100%; }

#main {
  margin-left: var(--sidebar-w);
  padding: 28px 32px 56px;
  max-width: none;
}

/* The customer area is held to a centred column. It used to run edge to edge on
   the reasoning that a cap "left a third of a wide monitor empty", but measured
   on a 1920 screen that gave a 1609px content column — 213 characters to a line
   against the 50-75 Baymard measured as comfortable and the 80 WCAG 1.4.8 allows
   at most. Baymard's testing found copy past 80 characters a line was skipped 41%
   more often, and testers called it "intimidating and overwhelming", which is the
   complaint here. The empty sides are not waste: they bound the page so the eye
   knows where a column starts and stops.

   Done with padding rather than max-width plus auto margins, because #main is
   already offset by the sidebar and auto margins cannot centre against that. The
   `max()` keeps the ordinary 32px gutter until the screen is wide enough to have
   room to give away, so nothing changes below ~1550px.

   The back office is deliberately excluded — dense staff tables want the width. */
.client-area #main {
  /* The sidebar has to come out by hand. A percentage inside padding resolves
     against the containing block — the body, the full window — not against
     #main, so `(100% - --shell-max) / 2` counted the sidebar's 232px twice and
     squeezed the column to 1048px. */
  padding-inline: max(32px, (100% - var(--sidebar-w) - var(--shell-max)) / 2);
}

/* --------------------------------------------------------------- panels -- */

/* Cards, not bands. Each of these is a white surface lifted off the grey page;
   elevation is what separates them now, so the hairline border comes off — a
   border and a shadow together read as two competing edges. */
.panel, .tile, .notif, .ins, .offer, .article, .faq, .invacct {
  background: var(--bg-card);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 20px;
}
.panel { margin-bottom: 20px; }

.tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
/* Elevation change only. The 2px slide toward the cursor was named as one of
   the generated-template tells and is not coming back with the shadows. */
.tile {
  transition: box-shadow 150ms var(--ease-out);
}
.tile:hover { box-shadow: var(--shadow-hover); }
.tile b { display: block; font-size: 22px; font-weight: 700; margin-top: 2px; color: var(--text-primary); }
.tile > div:first-child { font-size: 12px; color: var(--text-secondary); font-weight: 500; }
.tile .muted { font-size: 11px; }

/* The two .col wrappers dissolve so their panels become grid items directly:
   on a wide screen that means four columns of panels rather than two very
   wide ones, and it still collapses to a single column on a phone. */
.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 16px;
  align-items: start;
}
.col { display: contents; }
.cols > .panel, .cols .col > .panel, .cols .col > table { margin-bottom: 0; }
.wide { overflow-x: auto; }

/* --------------------------------------------------------------- tables -- */

/* Every table in the shell is wrapped in one of these by renderShell, so a
   table wider than a phone scrolls on its own instead of dragging the whole
   page sideways and clipping the navigation. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin-bottom: 16px;
}
.table-wrap > table { margin-bottom: 0; }
.panel > .table-wrap:last-child { margin-bottom: 0; }


table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-card);
  margin-bottom: 16px;
  font-size: 13px;
}
th, td {
  border: none;
  border-bottom: 1px solid var(--border-soft);
  padding: 10px 12px;
  text-align: left;
  vertical-align: middle;
}
th {
  background: var(--bg-muted);
  font-weight: 600;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background 120ms ease; }
tbody tr:hover { background: var(--bg-muted); }
/* tables nested inside a panel shouldn't double up the chrome */
.panel table { box-shadow: none; border: 1px solid var(--border-soft); margin-bottom: 0; }

/* -------------------------------------------------------------- controls -- */

button, .btn {
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 10px 18px;
  min-height: 42px;
  margin: 0 8px 6px 0;
  color: var(--brand-blue-hover);
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: box-shadow 150ms var(--ease-out), background 150ms ease, border-color 150ms ease;
}
/* Still no lift. The restyle brought shadows back, but a control that jumps
   2px toward the cursor was named as a generated-template tell and stays gone;
   hover is a darker edge, a tint and a shadow, nothing that moves. */
button:hover, .btn:hover {
  border-color: var(--brand-blue-primary);
  background: var(--bg-muted);
  box-shadow: var(--shadow-card);
}
button:active, .btn:active { transform: scale(0.98); box-shadow: none; }
button:focus-visible, .btn:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--brand-blue-primary);
  outline-offset: 2px;
}

button[type="submit"], .btn-primary {
  background: var(--brand-blue-primary);
  border-color: var(--brand-blue-primary);
  color: var(--text-on-dark);
  min-height: 48px;
  padding: 14px 28px;
  box-shadow: var(--shadow-card);
}
button[type="submit"]:hover, .btn-primary:hover {
  background: var(--brand-blue-hover);
  border-color: var(--brand-blue-hover);
  box-shadow: var(--shadow-hover);
}
button[type="submit"]:active, .btn-primary:active {
  background: var(--brand-blue-hover);
  transform: scale(0.98);
  box-shadow: none;
}

button:disabled, .btn:disabled, button[disabled] {
  background: #E2E8F0;
  border-color: var(--border-strong);
  color: var(--text-muted);
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

input, select, textarea {
  /* several fields carry an HTML size/cols attribute, which on a phone makes
     them wider than the screen and drags the whole page sideways */
  max-width: 100%;
  font-family: inherit;
  font-size: 14px;
  color: var(--text-primary);
  background: var(--bg-card);
  border: 1px solid var(--silver-strong);
  border-radius: var(--radius-sm);
  padding: 13px 14px;
  min-height: 48px;
  margin: 0 6px 4px 0;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
/* Outlined-field focus: the edge thickens to brand rather than growing a wide
   glow. box-shadow does the second pixel instead of border-width, so the
   control does not change size and the text inside never reflows. */
input:focus, select:focus, textarea:focus {
  border-color: var(--brand-blue-primary);
  box-shadow: inset 0 0 0 1px var(--brand-blue-primary);
  outline: none;
}
input::placeholder { color: var(--text-muted); }
textarea { min-height: 96px; line-height: 1.5; padding-top: 12px; }

/* Base field block. There was no base rule before this — only three
   contextual variants (.filters, .apply-card, .auth-card), which still
   override it. Label above the control, in the retail-app register. */
.field { display: block; margin-bottom: 16px; }
.field > label {
  display: block;
  margin: 0 0 6px 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-secondary);
  letter-spacing: 0.005em;
}
.field:focus-within > label { color: var(--brand-blue-primary); }
.field > input, .field > select, .field > textarea { width: 100%; margin-right: 0; }

label { font-size: 13px; font-weight: 500; color: var(--text-secondary); margin-right: 10px; }
/* A checkbox is not a text field. Without this it picks up width:100%,
   min-height and padding from the rules above and renders as a huge box. */
input[type="checkbox"], input[type="radio"] {
  flex: none;
  width: 16px;
  height: 16px;
  min-height: 0;
  padding: 0;
  margin: 0 6px 0 0;
  accent-color: var(--brand-blue-primary);
}
input[type="file"] { padding: 7px; background: var(--bg-muted); }

/* ------------------------------------------------------------ quick nav -- */

.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; }
.actions a {
  display: inline-block;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  color: var(--brand-blue-hover);
  font-weight: 600;
  font-size: 13px;
  text-decoration: none;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
}
.actions a:hover {
  text-decoration: none;
  border-color: var(--brand-blue-primary);
  background: var(--bg-muted);
}

/* horizontal snap carousel for narrow screens */
.scroll-carousel { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.scroll-carousel > * { scroll-snap-align: center; }

/* ---------------------------------------------------------- list states -- */

.notif, .ins, .offer, .article, .faq { margin-bottom: 12px; }
.notif.unread { border-left: 4px solid var(--brand-blue-primary); }
.notif .when { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

.ins.warning { border-left: 4px solid var(--accent-red); }
.ins.suggestion { border-left: 4px solid var(--brand-blue-primary); }
.ins.info { border-left: 4px solid var(--border-strong); }
.ins .tag {
  display: inline-block;
  margin-top: 8px;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  background: var(--bg-muted);
  border: 1px solid var(--border-soft);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: .4px;
}
.ins.warning .tag { background: #FEF2F2; border-color: #FECACA; color: #B91C1C; }
.ins.suggestion .tag { background: #EFF6FF; border-color: #BFDBFE; color: var(--brand-blue-hover); }

.offer img { max-width: 100%; height: auto; display: block; margin-bottom: 12px; border-radius: var(--radius-sm); }
.faq h3 { margin-bottom: 6px; }
.cat { margin-top: 20px; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: var(--text-muted); }

/* ------------------------------------------------------------ dashboard -- */

/* Main column plus a fixed rail, the shape most retail banking overviews
   settle on: balances and activity get the width, everything advisory sits
   to the side. Below 1100px the rail drops underneath. */
.dash {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 350px);
  gap: 20px;
  align-items: start;
}
.dash-main, .dash-side { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

.dash-head { margin-bottom: 18px; }
.dash-head h2 { margin-bottom: 2px; }
.dash-head .muted { margin: 0; }

/* Section headings are set small and lettered out, with a short silver rule
   beneath. Institutional stylesheets use a label, not a big heading, to open a
   section — the rule does the separating that a card border used to do. */
.sec-head {
  position: relative;
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-soft);
}
/* The silver sits on the divider itself, not under the heading text — the row
   is baseline-aligned, so anything hung off the h3 would float above the rule. */
.sec-head::after {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  bottom: -1px;
  width: 34px;
  height: 2px;
  background: var(--silver);
}
.sec-head h3 {
  margin: 0;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.sec-head a { font-size: 12.5px; font-weight: 600; }

/* ---- accounts ---- */
/* Navy filled tiles rather than white cards. In the retail apps this was drawn
   from, the balances are the one block of solid brand colour on the overview —
   everything else is white, so the eye lands on money first. Contrast on
   #12233A: white 15.8:1, the 82% white sublabels ~11:1, the 62% number ~5.9:1,
   so every line clears AA as body text. */
.acct-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 16px; }
.acct {
  padding: 18px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: var(--brand-navy-hero);
  color: var(--text-on-dark);
  box-shadow: var(--shadow-card);
  transition: box-shadow 150ms var(--ease-out);
}
.acct:hover { box-shadow: var(--shadow-hover); }
.acct-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.acct-id { display: flex; align-items: center; gap: 9px; min-width: 0; }
.acct-id .acct-badge {
  width: 30px; height: 30px; font-size: 9.5px;
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.24);
  color: var(--text-on-dark);
}
.acct-name { font-size: 12px; font-weight: 600; color: rgba(255, 255, 255, 0.82); }
.acct-bal { font-size: 26px; font-weight: 700; line-height: 1.1; letter-spacing: -0.5px; color: var(--text-on-dark); }
.acct-cur { font-size: 13px; font-weight: 600; color: rgba(255, 255, 255, 0.72); margin-inline-start: 5px; }
.acct-num { margin-top: 4px; font-size: 12px; color: rgba(255, 255, 255, 0.62); font-variant-numeric: tabular-nums; }
.acct-links {
  display: flex; gap: 12px;
  margin-top: 12px; padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  font-size: 12.5px; font-weight: 600;
}
.acct-links a { color: var(--text-on-dark); }
.acct-links a:hover { color: #FFFFFF; }
/* The pill sits on navy here, not on the page, so its own light palette would
   vanish. Scoped to the tile so pills elsewhere are untouched. */
.acct .pill {
  background: rgba(255, 255, 255, 0.16);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--text-on-dark);
}

.pill {
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .4px;
  border: 1px solid transparent;
}
.pill.active { background: #ECFDF5; border-color: #A7F3D0; color: #047857; }
.pill.pending, .pill.requested { background: #FFFBEB; border-color: #FDE68A; color: #B45309; }
.pill.blocked, .pill.cancelled, .pill.rejected { background: #FEF2F2; border-color: #FECACA; color: #B91C1C; }
.pill.closed { background: var(--bg-muted); border-color: var(--border-strong); color: var(--text-secondary); }

/* ---- flags and the pickers that carry them ---------------------------- */
/* Flags are inline SVG, not emoji: Windows has no flag glyphs and would show
   a pair of letters instead. */
.flag {
  flex: none;
  width: 22px; height: 15px;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.14) inset;
  object-fit: cover;
}
.flag-letters {
  display: grid; place-items: center;
  background: var(--bg-muted);
  color: var(--text-secondary);
  font-size: 9px; font-weight: 700; letter-spacing: .3px;
}
.flag-lg { width: 26px; height: 18px; }

.flag-picker { position: relative; display: inline-block; }
.flag-picker-btn {
  display: flex; align-items: center; gap: 8px;
  margin: 0;
  padding: 7px 11px;
  min-height: 36px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  font: inherit; font-size: 13px; font-weight: 500;
  color: var(--text-primary);
  cursor: pointer;
}
.flag-picker-btn:hover { border-color: var(--brand-blue-primary); transform: none; box-shadow: none; }
.flag-picker-btn[aria-expanded="true"] { border-color: var(--brand-blue-primary); }
.flag-picker-label { white-space: nowrap; }
.flag-picker-caret { flex: none; color: var(--text-muted); transition: transform 150ms ease; }
.flag-picker-btn[aria-expanded="true"] .flag-picker-caret { transform: rotate(180deg); }

.flag-picker-list {
  position: absolute;
  z-index: 40;
  inset-inline-start: 0;
  top: calc(100% + 5px);
  min-width: 100%;
  max-height: 300px;
  overflow-y: auto;
  padding: 5px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  /* The panel paints its own surface, so it has to paint its own text too.
     Options are `color: inherit`, and on the login and registration screens
     the host (.auth-lang) is white-on-navy — which left every option white on
     this white panel and invisible. Anything that opens over its own
     background cannot borrow the foreground of whatever it opened from. */
  color: var(--text-primary);
  box-shadow: var(--shadow-float);
}
.flag-option {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  margin: 0;
  padding: 7px 9px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  box-shadow: none;
  font: inherit; font-size: 13px; font-weight: 500;
  color: inherit;
  text-align: start;
  white-space: nowrap;
  cursor: pointer;
}
.flag-option:hover, .flag-option:focus-visible {
  background: var(--bg-muted);
  transform: none; box-shadow: none; border: 0;
}
.flag-option[aria-selected="true"] { background: #EFF6FF; }
.flag-option-sub { margin-inline-start: auto; font-size: 11.5px; color: var(--text-secondary); }

/* on the navy login and registration screens the picker follows the surface */
.auth-lang .flag-picker-btn, .reg-top .flag-picker-btn {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--text-on-dark);
}
.auth-lang .flag-picker-btn:hover, .reg-top .flag-picker-btn:hover { border-color: rgba(255, 255, 255, 0.55); }
.auth-lang .flag-picker-caret, .reg-top .flag-picker-caret { color: rgba(255, 255, 255, 0.7); }

/* in the sidebar it spans the column like the select it replaced */
#sidebar .flag-picker { display: block; }
#sidebar .flag-picker-btn { width: 100%; }
#sidebar .flag-picker-list { max-height: 260px; }
/* Set by flagPicker when there is not room below the button. */
.flag-picker-list.drop-up { top: auto; bottom: calc(100% + 5px); }

/* a circular flag reads better than a lettered disc on account rows */
.acct-flag {
  display: grid; place-items: center;
  flex: none;
  width: 36px; height: 36px;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  border-radius: 50%;
  background: var(--bg-muted);
}
.acct-flag .flag { width: 100%; height: 100%; border-radius: 0; box-shadow: none; }
.acct-id .acct-flag { width: 30px; height: 30px; }
.acct-hero .acct-flag { width: 46px; height: 46px; }
.total-chip .flag { margin-inline-end: 2px; }
.total-chip { align-items: center; }

/* asset rows on the investment page: every mark is the same 24px square,
   whether it holds a flag or an instrument icon, so the column lines up */
.asset-cell { display: flex; align-items: center; gap: 9px; min-width: 0; }
.asset-cell b { font-weight: 600; }
.asset-cell-name { font-size: 12px; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.asset-mark {
  display: grid; place-items: center;
  flex: none;
  width: 24px; height: 24px;
  overflow: hidden;
  border: 1px solid var(--border-soft);
  border-radius: 6px;
  background: var(--bg-muted);
}
.asset-mark .flag { width: 100%; height: 100%; border-radius: 0; box-shadow: none; }

/* ---- one-line account switcher ---------------------------------------- */
/* A single row naming the account you are looking at, which opens into every
   account you hold. Picking one lands on that account's own history page. */
/* the entry animation on every #main child makes it a stacking context, so
   the host has to be lifted or the open list falls behind later siblings */
#main > .switch-host { position: relative; z-index: 40; }
.acct-switch { position: relative; width: min(420px, 100%); }
.acct-switch-btn {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  min-height: 52px;
  margin: 0;
  padding: 9px 13px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  font: inherit;
  color: var(--text-primary);
  text-align: start;
  cursor: pointer;
}
.acct-switch-btn:hover { border-color: var(--brand-blue-primary); transform: none; }
.acct-switch-btn[aria-expanded="true"] { border-color: var(--brand-blue-primary); }
.acct-switch-main { min-width: 0; }
.acct-switch-title {
  font-size: 13.5px; font-weight: 700; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acct-switch-sub { font-size: 11.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.acct-switch-amt { margin-inline-start: auto; font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.acct-switch-caret { flex: none; color: var(--text-muted); transition: transform 150ms ease; }
.acct-switch-btn[aria-expanded="true"] .acct-switch-caret { transform: rotate(180deg); }

.acct-badge {
  display: grid; place-items: center;
  flex: none;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand-navy-hero) 0%, var(--brand-blue-primary) 100%);
  color: var(--text-on-dark);
  font-size: 10.5px; font-weight: 700; letter-spacing: .3px;
}
.acct-badge.muted-badge { background: linear-gradient(135deg, #64748B 0%, #94A3B8 100%); }

.acct-switch-list {
  position: absolute;
  z-index: 30;
  inset-inline-start: 0;
  top: calc(100% + 6px);
  min-width: 100%;
  max-height: 330px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-float);
}
.acct-option {
  display: flex; align-items: center; gap: 11px;
  width: 100%;
  margin: 0;
  padding: 9px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  box-shadow: none;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
}
.acct-option:hover, .acct-option:focus-visible {
  background: var(--bg-muted);
  transform: none;
  box-shadow: none;
  border: 0;
}
.acct-option[aria-selected="true"] { background: #EFF6FF; }
.acct-option .amt { margin-inline-start: auto; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.acct-option-sub { font-size: 11.5px; color: var(--text-secondary); }
.acct-switch-group {
  padding: 8px 10px 4px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-muted);
}

/* ---- per-currency totals ------------------------------------------------ */
.totals { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 18px; }
.total-chip {
  display: flex; align-items: baseline; gap: 9px;
  padding: 9px 15px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-pill);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}
.total-chip .cur { font-size: 11px; font-weight: 700; letter-spacing: .5px; color: var(--text-secondary); }
.total-chip .val { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ---- account detail header --------------------------------------------- */
.acct-hero { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.acct-hero .acct-badge { width: 46px; height: 46px; font-size: 12px; }
.acct-hero-main { min-width: 0; }
.acct-hero-name { display: flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 700; }
.acct-hero-num { font-size: 12.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.acct-hero-bal { margin-inline-start: auto; font-size: 28px; font-weight: 700; letter-spacing: -.5px; font-variant-numeric: tabular-nums; }
.acct-hero-bal span { margin-inline-start: 5px; font-size: 13px; font-weight: 600; color: var(--text-secondary); }

.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin-bottom: 14px; }
.filters .field { margin: 0; }
.filters .field label {
  display: block; margin-bottom: 6px;
  font-size: 12px; font-weight: 600; color: var(--text-secondary);
}
.filters input, .filters select, .filters button { margin: 0; min-height: 38px; }

/* ---- the card face ---- */
.card-rail {
  display: flex; gap: 14px;
  overflow-x: auto;
  padding-bottom: 4px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.card-rail > * { scroll-snap-align: start; }

.bankcard {
  position: relative;
  flex: none;
  width: 320px;
  aspect-ratio: 1.586;            /* ID-1, the proportion of a real card */
  padding: 17px 19px;
  border-radius: 15px;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
  color: #fff;
  background: linear-gradient(135deg, #06203C 0%, #0F3D6B 46%, #117ACA 100%);
  box-shadow: 0 14px 30px rgba(2, 14, 28, 0.3);
}
/* a light sweep across the top-right corner, the way a printed card catches it */
.bankcard::after {
  content: '';
  position: absolute; inset: 0;
  background:
    radial-gradient(120% 80% at 88% -12%, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0) 58%),
    linear-gradient(200deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0) 42%);
  pointer-events: none;
}
.bankcard > * { position: relative; z-index: 1; }
.bankcard.credit { background: linear-gradient(135deg, #14213D 0%, #3A2A5E 48%, #6D4AA6 100%); }
.bankcard.requested { background: linear-gradient(135deg, #334155 0%, #52606D 50%, #7B8794 100%); }
.bankcard.blocked, .bankcard.cancelled, .bankcard.rejected { filter: grayscale(0.8); opacity: 0.78; }

.bankcard-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.bankcard-brand { display: flex; align-items: center; gap: 8px; }
.bankcard-mark {
  width: 26px; height: 26px;
  border-radius: 7px;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.34);
  font-size: 11px; font-weight: 700; letter-spacing: .5px;
}
.bankcard-name { font-size: 12.5px; font-weight: 700; letter-spacing: .3px; }
.bankcard-kind {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 1.2px;
  color: rgba(255, 255, 255, 0.82);
}

.bankcard-mid { display: flex; align-items: center; gap: 12px; }
/* chip and contactless glyph — both generic, no scheme marks anywhere */
.bankcard-chip {
  position: relative;
  width: 38px; height: 28px;
  border-radius: 5px;
  background: linear-gradient(145deg, #F5D98B 0%, #D8B563 45%, #F2E2AE 100%);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.16);
}
.bankcard-chip::before, .bankcard-chip::after {
  content: '';
  position: absolute;
  background: rgba(0, 0, 0, 0.22);
}
.bankcard-chip::before { left: 0; right: 0; top: 50%; height: 1px; }
.bankcard-chip::after { top: 4px; bottom: 4px; left: 50%; width: 1px; }
.bankcard-wave { opacity: 0.85; }

.bankcard-pan {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 2.2px;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.28);
}
.bankcard-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.bankcard-label {
  margin-bottom: 2px;
  font-size: 8px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px;
  color: rgba(255, 255, 255, 0.62);
}
.bankcard-value { font-size: 12.5px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; }
.bankcard-meta { margin-top: 8px; font-size: 12px; color: var(--text-secondary); }
.bankcard-meta b { color: var(--text-primary); }

.card-slot { flex: none; width: 320px; }
.card-empty {
  display: grid; place-items: center;
  aspect-ratio: 1.586;
  padding: 16px;
  border: 1px dashed var(--border-strong);
  border-radius: 15px;
  background: var(--bg-muted);
  color: var(--text-secondary);
  font-size: 13px; font-weight: 600;
  text-align: center;
}

/* ---- credit report check ---------------------------------------------- */
.credit-steps {
  margin: 0 0 18px;
  padding-inline-start: 20px;
  font-size: 13px;
  color: var(--text-secondary);
}
.credit-steps li { margin-bottom: 5px; }
.credit-steps li::marker { color: var(--brand-blue-primary); font-weight: 700; }
#creditDetail { margin-top: 14px; }
#creditDetail .card-actions { margin-top: 14px; }
/* The country list is long, so it gets more room than a currency picker.
   The field needs a flex basis too: without one it shrinks to the button and
   the button, sized at 100% of it, shrinks to its own text. */
#creditGate .apply-card .field { flex: 1 1 260px; max-width: 360px; }
#creditGate .flag-picker { display: block; width: 100%; }
#creditGate .flag-picker-btn { width: 100%; }
#creditGate .flag-picker-list { max-height: 340px; }
#applyPanel .apply-card:has(:disabled) { opacity: .55; }

/* ---- cards page: the same face, with the detail and controls beneath it ---- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 18px;
  align-items: start;
  margin-bottom: 22px;
}
.card-item { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
/* on this page the face flexes with its column instead of staying at rail width */
.card-item .bankcard { width: 100%; max-width: 370px; }

.card-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(116px, 1fr)); gap: 10px 14px; }
.card-fact-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  color: var(--text-muted);
}
.card-fact-value { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }

.card-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border-soft);
}
.card-actions input { width: 92px; margin: 0; }
.card-actions input.merchant { width: 136px; }
.card-actions button { margin: 0; }
.card-actions .spend {
  display: flex; align-items: center; gap: 6px;
  padding-inline-end: 8px;
  border-inline-end: 1px solid var(--border-soft);
}

.apply-card { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; }
/* A wrapper that groups controls for showing and hiding, without becoming a
   layout box itself. `#openAccRow` is a <span> holding two labelled fields and
   a button: as an ordinary inline box the fields stacked vertically inside it
   and sat out of line with the buttons beside them. `display: contents` lifts
   its children into the flex row so they align like every other control.
   Hiding still works — the base layer's `[hidden] { display: none !important }`
   outranks this. */
.apply-card .field-group { display: contents; }
.apply-card .field { margin: 0; }
.apply-card .field label {
  display: block; margin-bottom: 6px;
  font-size: 12px; font-weight: 600; color: var(--text-secondary);
}
.apply-card select { margin: 0; min-height: 38px; }
.apply-card button { margin: 0; min-height: 38px; }

/* ---- side rail ---- */
.dash-side .panel { margin-bottom: 0; padding: 14px 16px; }
.dash-side h3 { font-size: 14px; }
.feed { display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.feed-item { display: flex; gap: 8px; align-items: flex-start; color: var(--text-secondary); }
.feed-item.unread { color: var(--text-primary); font-weight: 500; }
.feed-dot {
  flex: none;
  width: 6px; height: 6px; margin-top: 6px;
  border-radius: 50%;
  background: var(--border-strong);
}
.feed-item.unread .feed-dot { background: var(--brand-blue-primary); }
.feed-more { margin: 10px 0 0; font-size: 12.5px; font-weight: 600; }

.offer-row { display: flex; gap: 10px; align-items: center; }
.offer-row img { flex: none; width: 52px; height: 52px; object-fit: cover; border-radius: var(--radius-sm); }
.offer-row b { font-size: 13px; }

td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

@media (max-width: 1100px) {
  .dash { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .bankcard, .card-slot { width: 270px; }
  .acct-bal { font-size: 23px; }
}

/* --------------------------------------------------------- login screen -- */

.auth-page,
.reg-page {
  /* The diagonal rim: where the photo wedge begins at the top and at the
     bottom of the viewport. Re-angle the whole split by tuning these two. */
  --cut-top: 78%;
  --cut-bottom: 48%;
  --scrim-angle: 100deg;

  /* One photograph for every visitor. The painted gradient behind it echoes the
     same open sky, so the page still reads correctly if the file is missing.
     data-tod is still set on <body>, but it now only drives the greeting. */
  --scene-photo: url('/img/scene/coast-day.jpg?v=202610261955');
  --scene-paint: linear-gradient(180deg, #BFDCEF 0%, #D8E7F2 38%, #E7E2D6 66%, #CBBEAA 100%);
  --base-top: #04182E;
  --base-mid: #0A2540;
  --base-bottom: #0E3A63;

  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  overflow-x: hidden;
  color: var(--text-on-dark);
  background: linear-gradient(155deg, var(--base-top) 0%, var(--base-mid) 52%, var(--base-bottom) 100%);
}

.auth-scene {
  position: absolute;
  inset: 0;
  background-image: var(--scene-paint);
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
  clip-path: polygon(var(--cut-top) 0, 100% 0, 100% 100%, var(--cut-bottom) 100%);
  animation: sceneIn 900ms var(--ease-out) both;
}
/* The photo sits in its own layer so it can be given a smaller area than the
   wedge. The source files are only ~550px across; stretching one over a whole
   1440x900 viewport magnified it about 2.6x and the softness showed. */
.auth-photo {
  position: absolute;
  inset: 0;
  background-image: var(--scene-photo);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}

/* Blends the wedge into the navy along the rim and keeps the lower edge calm. */
.auth-scene::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(var(--scrim-angle), var(--base-mid) 0%, rgba(10, 37, 64, 0.55) 13%, rgba(10, 37, 64, 0) 40%),
    linear-gradient(180deg, rgba(4, 24, 46, 0.26) 0%, rgba(4, 24, 46, 0) 32%, rgba(4, 24, 46, 0.48) 100%);
}
/* The rim itself: a 2px lit line running along the cut. */
.auth-rim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.62) 0%, rgba(255, 255, 255, 0.26) 48%, rgba(255, 255, 255, 0.07) 100%);
  clip-path: polygon(
    var(--cut-top) 0,
    calc(var(--cut-top) + 2px) 0,
    calc(var(--cut-bottom) + 2px) 100%,
    var(--cut-bottom) 100%);
}

@media (min-width: 901px) {
  /* Desktop: the photo covers only the middle of the wedge and feathers into
     the painted gradient above and below, which drops the magnification to
     roughly 1.5x. The rim still runs the full height of the page. */
  .auth-photo {
    inset: 26% 0 26% 56%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 90%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 10%, #000 90%, transparent 100%);
  }
  [dir="rtl"] .auth-photo { inset: 26% 56% 26% 0; }
}

.auth-shell {
  position: relative;
  z-index: 2;
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 20px;
  padding: clamp(18px, 2.6vw, 30px) clamp(20px, 5vw, 60px);
}

.auth-top { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.auth-top .brand { margin-bottom: 0; }
.auth-page .brand-name { color: var(--text-on-dark); }
.auth-page .brand-sub { color: rgba(255, 255, 255, 0.62); }
.auth-page .brand-mark {
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.32);
}

.auth-lang { display: flex; align-items: center; gap: 8px; font-size: 12px; color: rgba(255, 255, 255, 0.72); }
.auth-lang select {
  margin: 0;
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--text-on-dark);
}
.auth-lang select option { color: var(--text-primary); }

.auth-body { display: flex; align-items: center; justify-content: flex-start; }
.auth-col { width: min(430px, 100%); display: flex; flex-direction: column; gap: 18px; }

.auth-greet {
  margin-bottom: 8px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.auth-intro h1 {
  margin-bottom: 10px;
  color: var(--text-on-dark);
  font-size: clamp(30px, 3.4vw, 42px);
}
.auth-intro p {
  margin: 0;
  max-width: 42ch;
  font-size: 14.5px;
  color: rgba(255, 255, 255, 0.78);
}

.auth-card {
  padding: 26px 26px 22px;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  color: var(--text-primary);
  box-shadow: 0 24px 60px rgba(2, 14, 28, 0.38);
}
.auth-card h2 { font-size: 19px; margin-bottom: 16px; }
.auth-card .field { margin-bottom: 14px; }
.auth-card .field label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
}
.auth-card input { width: 100%; margin: 0; min-height: 42px; }
.auth-card button { width: 100%; margin: 0; }
.auth-card .btn-ghost { min-height: 44px; }
.auth-msg { margin: 10px 0 0; min-height: 16px; font-size: 12.5px; color: var(--accent-red); }
.auth-card .divider {
  display: flex; align-items: center; gap: 10px;
  margin: 16px 0;
  font-size: 12px;
  color: var(--text-muted);
}
.auth-card .divider::before, .auth-card .divider::after {
  content: ''; flex: 1; height: 1px; background: var(--border-soft);
}
.auth-alt { margin: 14px 0 0; text-align: center; font-size: 13px; }

.creds {
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(6px);
  font-size: 11.5px;
  line-height: 1.75;
  color: rgba(255, 255, 255, 0.76);
}
.creds > summary {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  list-style: none;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.88);
}
.creds > summary::-webkit-details-marker { display: none; }
.creds > summary::after { content: '+'; margin-inline-start: auto; font-size: 15px; opacity: 0.7; }
.creds[open] > summary::after { content: '\2212'; }
.creds .creds-body { padding: 0 14px 12px; }
.creds b { color: #fff; font-weight: 600; }

.auth-foot { font-size: 11.5px; color: rgba(255, 255, 255, 0.5); }

[dir="rtl"] .auth-page { --scrim-angle: 260deg; }
[dir="rtl"] .auth-scene {
  clip-path: polygon(0 0, calc(100% - var(--cut-top)) 0, calc(100% - var(--cut-bottom)) 100%, 0 100%);
}
[dir="rtl"] .auth-rim {
  clip-path: polygon(
    calc(100% - var(--cut-top)) 0,
    calc(100% - var(--cut-top) - 2px) 0,
    calc(100% - var(--cut-bottom) - 2px) 100%,
    calc(100% - var(--cut-bottom)) 100%);
}
[dir="rtl"] .auth-body { justify-content: flex-end; }

@keyframes sceneIn { from { opacity: 0; } to { opacity: 1; } }

@media (max-width: 900px) {
  /* Portrait has no room for a vertical wedge, so the same cut runs across the
     top instead — deeper on the left, shallow on the right — and the card sits
     below the rim rather than on top of it. */
  .auth-page { --m-cut-left: 40%; --m-cut-right: 25%; }
  .auth-page .auth-scene {
    clip-path: polygon(0 0, 100% 0, 100% var(--m-cut-right), 0 var(--m-cut-left));
  }
  /* only the band is visible, so that is all the photo has to cover — at full
     page height cover would magnify it 2.3x for nothing */
  .auth-page .auth-photo { bottom: auto; height: var(--m-cut-left); }
  .auth-page .auth-scene::after {
    background: linear-gradient(180deg, rgba(4, 24, 46, 0.64) 0%, rgba(4, 24, 46, 0.5) 28%, rgba(4, 24, 46, 0.26) 62%, rgba(4, 24, 46, 0.55) 100%);
  }
  .auth-page .auth-rim {
    background: linear-gradient(90deg, rgba(255, 255, 255, 0.14) 0%, rgba(255, 255, 255, 0.5) 100%);
    clip-path: polygon(
      0 var(--m-cut-left),
      100% var(--m-cut-right),
      100% calc(var(--m-cut-right) + 2px),
      0 calc(var(--m-cut-left) + 2px));
  }
  [dir="rtl"] .auth-page .auth-scene {
    clip-path: polygon(0 0, 100% 0, 100% var(--m-cut-left), 0 var(--m-cut-right));
  }
  [dir="rtl"] .auth-page .auth-rim {
    clip-path: polygon(
      0 var(--m-cut-right),
      100% var(--m-cut-left),
      100% calc(var(--m-cut-left) + 2px),
      0 calc(var(--m-cut-right) + 2px));
  }
  /* the column dissolves into the shell grid so the card can be pinned to the
     bottom, keeping the rim clear of it */
  .auth-body, .auth-col { display: contents; }
  .auth-shell { grid-template-rows: auto auto 1fr auto auto; }
  .auth-intro { align-self: start; }
  .auth-card { align-self: end; }
}
@media (max-width: 560px) {
  .auth-top .brand-sub { display: none; }
  .auth-card { padding: 20px 18px 18px; }
}
/* Laptop-height screens: tighten the rhythm so the card never needs a scroll. */
@media (max-height: 860px) {
  .auth-shell { padding-top: 16px; padding-bottom: 16px; gap: 12px; }
  .auth-col { gap: 12px; }
  .auth-greet { margin-bottom: 6px; }
  .auth-intro h1 { font-size: clamp(26px, 2.6vw, 32px); margin-bottom: 8px; }
  .auth-intro p { font-size: 13.5px; }
  .auth-card { padding: 20px 22px 18px; }
  .auth-card h2 { margin-bottom: 12px; }
  .auth-card .field { margin-bottom: 11px; }
  .auth-card .divider { margin: 12px 0; }
  .auth-alt { margin-top: 12px; }
  .auth-foot { display: none; }
}

/* Short phones: the intro loses its description and the band flattens, so the
   rim still passes between the heading and the card instead of through them. */
@media (max-width: 900px) and (max-height: 760px) {
  .auth-page { --m-cut-left: 28%; --m-cut-right: 20%; }
  .auth-intro p { display: none; }
  .auth-card { padding: 16px 16px 14px; }
  .auth-card h2 { margin-bottom: 10px; }
  .auth-card .field { margin-bottom: 9px; }
  .auth-card input { min-height: 40px; }
  .auth-card .divider { margin: 10px 0; }
  .auth-alt { margin-top: 10px; }
  .creds > summary { padding: 8px 12px; }
}

/* Short phones: the last few pixels that keep the card off a scrollbar. */
@media (max-width: 900px) and (max-height: 880px) {
  .auth-shell { gap: 9px; padding-bottom: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .auth-scene { animation: none; }
}

/* ---- login: photo across the page, form on the left, links beside it ----- */
/* The wedge and its rim belong to the registration hero now. Here the picture
   runs edge to edge and a wash across the left carries the form, which is the
   arrangement most retail banks land on. Brand colour stays blue throughout. */
.auth-page {
  color: var(--text-primary);
  background: var(--bg-card);
  --photo-w: min(560px, 34vw);
  /* How far the picture pulls in from the right edge so it sits nearer the
     middle. Nothing below 1200px, where there is no width to spare, then it
     drifts inward as the viewport grows — about 400px on a 1865px screen. The
     content column subtracts the same value, so the two can never close the
     gap between them however wide the window gets. */
  --photo-end: clamp(0px, (100vw - 1200px) * 0.6, 400px);
  /* Where the picture's left edge falls, so the wash can be aimed at it. */
  --photo-x: calc(100vw - var(--photo-end) - var(--photo-w));
  /* This picture carries no vignette of its own — sampling it, the studio grey
     (210,212,211) runs hard to all four edges and her jacket (43,92,124) goes
     straight off the bottom. So: two straight fades, which between them take
     every edge and corner to nothing, and an oval over the top to round what is
     left. Centred at 53% 56% because she sits centre-right and low in frame.
     Declared here rather than on the picture so the aside's copy and the phone
     band's copy are fed by the same one. */
  --photo-feather:
    radial-gradient(ellipse 90% 95% at 53% 56%,
      rgba(0, 0, 0, 1) 0%,
      rgba(0, 0, 0, 0.98) 50%,
      rgba(0, 0, 0, 0.85) 70%,
      rgba(0, 0, 0, 0.55) 85%,
      rgba(0, 0, 0, 0.20) 95%,
      rgba(0, 0, 0, 0) 100%),
    linear-gradient(90deg, transparent 0%, #000 16%, #000 92%, transparent 100%),
    linear-gradient(180deg, transparent 0%, #000 14%, #000 86%, transparent 100%);
}
/* The picture now carries its own white vignette, so the surface under it has
   to be white or that vignette reads as a pale rectangle sitting on the tint.
   Rather than drop the tint from the whole page, a soft white halo is laid over
   the paint behind the picture and dissolves back into it. It goes on the
   scene's own background, not on ::after — ::after is generated after the photo
   and would paint the halo straight over the family. */
.auth-page .auth-scene {
  clip-path: none;
  animation: none;
  background-image:
    radial-gradient(ellipse calc(var(--photo-w) * 0.84) calc(var(--photo-w) * 0.62)
      at calc(var(--photo-x) + var(--photo-w) / 2) 46%,
      #fff 0%, #fff 68%, rgba(255, 255, 255, 0) 100%),
    var(--scene-paint);
}
.auth-page .auth-rim { display: none; }
/* ---- the right-hand column: headline, picture, benefits ------------------ */
/* The band it occupies is the one the picture used to have to itself. Three
   grid rows, and because the outer two are equal fractions the picture lands on
   the exact centre line whatever the headline and the list do above and below
   it — no coordinate has to be kept in step by hand. */
.auth-page .auth-aside {
  position: absolute;
  z-index: 3;
  inset-block: clamp(24px, 5vh, 60px) clamp(96px, 14vh, 130px);
  inset-inline-end: var(--photo-end);
  width: var(--photo-w);
  display: grid;
  grid-template-rows: 1fr auto 1fr;
  gap: clamp(14px, 2.2vh, 26px);
}
/* The band's lower inset exists to clear the promo strip. The reset page has no
   promo strip, only a 4px accent, so there it holds room for nothing and leaves
   the picture sitting about 40px above the optical centre. Keyed off the strip
   itself rather than a new class, so any auth page without one is covered. */
.auth-page:not(:has(.auth-promo)) .auth-aside {
  inset-block-end: clamp(24px, 5vh, 60px);
}
.aside-head {
  /* Centred in its own row rather than pushed against the picture, so the two
     spare rows read as even space instead of a gap at the top of the band. */
  align-self: center;
  margin: 0;
  color: var(--brand-navy-hero);
  font-size: clamp(17px, 1.3vw, 21px);
  font-weight: 700;
  line-height: 1.32;
  text-align: center;
  text-wrap: balance;
}
.aside-photo {
  width: 100%;
  aspect-ratio: 612 / 408;
  background-image: var(--scene-photo);
  background-size: cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
  -webkit-mask-image: var(--photo-feather);
  mask-image: var(--photo-feather);
  -webkit-mask-composite: source-in, source-in, source-over;
  mask-composite: intersect, intersect, add;
}
.aside-list {
  align-self: center;
  justify-self: center;
  display: grid;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.aside-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--text-secondary);
}
.aside-list li::before {
  content: '\2713';
  flex: none;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--brand-blue-primary);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}

.auth-page .auth-photo {
  /* The scene layer's copy is the phone band only; on desktop the picture is
     the middle row of .auth-aside instead. */
  display: none;
  /* Sized so the source is never enlarged. The file is 723x850; this box is
     smaller than that in both directions, so the browser scales it down and it
     stays sharp. Stretching it across the whole hero was what made it mushy.
     The bottom inset keeps it clear of the promo strip. */
  inset: clamp(24px, 5vh, 60px) var(--photo-end) clamp(96px, 14vh, 130px) auto;
  width: var(--photo-w);
  /* The picture is landscape, 612x408. Cropping it into a tall slot would mean
     scaling a 612px-wide source up about 1.8x, which is exactly the softness
     this slot was sized to avoid — so the slot takes the picture's proportions
     and centres itself in the band instead. At 560px wide it draws at 0.92x,
     a slight reduction, so it stays sharp. */
  height: calc(var(--photo-w) / 1.5);
  margin-block: auto;
  background-size: cover;
  background-position: 50% 50%;
  border-start-start-radius: var(--radius-lg);
  border-end-start-radius: var(--radius-lg);
  -webkit-mask-image: var(--photo-feather);
  mask-image: var(--photo-feather);
  /* Per layer, and the lowest must be `add`: it composites against transparent
     black, so `intersect` there would erase the picture entirely. */
  -webkit-mask-composite: source-in, source-in, source-over;
  mask-composite: intersect, intersect, add;
}
/* The wash used to be pinned to percentages of the viewport, which was fine
   while the picture was stuck to the right edge. Now that it moves, the stops
   are measured off --photo-x instead: white all the way to 150px short of the
   picture, gone again a sixth of the way into it. Percentages could not track
   both the text column and the picture, since they no longer move together.
   Squared off to 90deg for that reason — at 97deg the stops are measured along
   a tilted line and land about 5% wide of where the numbers say. */
.auth-page .auth-scene::after {
  background:
    linear-gradient(90deg,
      rgba(255, 255, 255, 1) 0,
      rgba(255, 255, 255, 0.95) calc(var(--photo-x) - 150px),
      rgba(255, 255, 255, 0.3) calc(var(--photo-x) + 20px),
      rgba(255, 255, 255, 0) calc(var(--photo-x) + var(--photo-w) * 0.16)),
    linear-gradient(180deg, rgba(255, 255, 255, 0.75) 0%, rgba(255, 255, 255, 0) 26%);
}

.auth-page .auth-shell { grid-template-rows: auto 1fr; padding-bottom: 0; }
.auth-page .brand-name { color: var(--text-primary); }
.auth-page .brand-sub { color: var(--text-muted); }
.auth-page .brand-mark {
  background: linear-gradient(135deg, var(--brand-navy-hero) 0%, var(--brand-blue-primary) 100%);
  border: 0;
}
.auth-page .auth-lang .flag-picker-btn {
  background: rgba(255, 255, 255, 0.85);
  border-color: var(--border-strong);
  color: var(--text-primary);
}
.auth-page .auth-lang .flag-picker-caret { color: var(--text-muted); }

/* the shell shares the page with the promo strip, which sits under it */
.auth-page { display: flex; flex-direction: column; }
.auth-page .auth-shell { flex: 1; min-height: 0; }
/* the single narrow column is the wedge layout; here it spans both columns */
/* Content runs up to the photo rather than to a fixed width, so the gap
   between them stays constant instead of growing with the viewport. */
.auth-page .auth-col {
  width: 100%;
  max-width: min(1240px, calc(var(--photo-x) - 150px));
  display: block;
}

.auth-welcome { margin-bottom: 22px; }
.auth-welcome h1 {
  margin: 0;
  color: var(--brand-navy-hero);
  font-size: clamp(24px, 2.8vw, 34px);
}
.auth-page .auth-greet {
  margin-bottom: 6px;
  color: var(--brand-blue-hover);
}

/* form on the left, everything else beside it */
.auth-cols {
  display: grid;
  grid-template-columns: minmax(0, 372px) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 64px);
  align-items: start;
}

.auth-page .auth-card {
  padding: 26px 26px 22px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 6px 20px rgba(15, 23, 42, 0.08);
}
.auth-page .auth-card h2 { color: var(--brand-navy-hero); }
.auth-card input[type="checkbox"] { width: 16px; min-height: 0; margin: 0; }

/* password with a reveal control sharing its box */
/* The eye sits beside the field, not on top of it. Floating it inside relied
   on padding-inline-end to keep the text clear, and that does not hold: once
   the value is longer than the box the input scrolls its own content, and the
   scrolled text renders straight through the reserved padding and under the
   icon. A generated password is exactly the case that overflows, so the one
   time the control matters most was the one time it was unreadable. */
/* The eye toggle overlays the field rather than sitting beside it. As a flex
   sibling it stole ~46px of width, so the password box came out visibly
   narrower than the email box above it. Now the input is full width like every
   other field and the toggle floats over its right edge, with padding reserving
   the space so the dots never run under the icon. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; min-width: 0; padding-inline-end: 44px; }
/* Selector deliberately two classes deep. `.auth-card button { width: 100% }`
   is (0,1,1) and beat a bare `.pw-toggle` at (0,1,0). */
.pw-wrap .pw-toggle {
  position: absolute;
  inset-inline-end: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 34px;
  min-width: 34px;
  height: 34px;
  min-height: 34px;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  color: var(--text-muted);
  cursor: pointer;
}
.pw-wrap .pw-toggle:hover { background: none; border: 0; box-shadow: none; color: var(--brand-blue-primary); }
.pw-toggle[aria-pressed="true"] { color: var(--brand-blue-primary); }

.auth-remember {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0 16px;
  font-size: 13px;
  color: var(--text-secondary);
  font-weight: 500;
}
.auth-remember input { margin: 0; }

/* the column of onward links, chevrons and all */
/* Centred against the sign-in card rather than pinned to its top edge.
   This column used to hold a third block of demo credentials, which made it
   roughly as tall as the card; with that gone it is 155px beside a 447px card,
   and anchoring it to the top left the remaining 292px reading as a hole rather
   than as space. Centring makes the row balance at any card height, which also
   means it survives the card growing when an error message appears. */
.auth-links {
  padding-top: 4px;
  align-self: center;
}

/* Above 1600 the composition used to stop growing while the window kept going.
   The picture is pinned --photo-end from the right and everything else derives
   from --photo-x (= viewport - end - width), including the content column's own
   max-width and the glow painted behind the picture. So bringing the picture
   back toward the edge and letting it grow widens the content and moves the
   glow with it, from one place. At 1900 this turns 415px of empty page on the
   right into 220px, and gives the sign-in column about 120px more to work
   with. */
@media (min-width: 1600px) {
  .auth-page {
    --photo-end: clamp(0px, (100vw - 1200px) * 0.28, 240px);
    --photo-w: min(640px, 34vw);
  }
  .auth-page .auth-cols { grid-template-columns: minmax(0, 420px) minmax(0, 1fr); }
}
.auth-links a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--brand-blue-hover);
}
.auth-links a:hover { text-decoration: none; color: var(--brand-navy-hero); }
.auth-links a svg { flex: none; transition: transform 150ms ease; }
.auth-links a:hover svg { transform: translateX(3px); }
.auth-links .creds { margin-top: 14px; }

/* The benefit list, in its new home beside the sign-in card. Same tick mark as
   it wore under the picture, left aligned instead of centred because it now
   sits in a column of left-aligned text rather than alone in a band. */
/* The employees screen. A colleague's photograph in the list, and the one time
   password shown after an account is created. Both live here rather than on a
   style attribute, which is what the design audit checks for. */
.staff-photo {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}
.staff-pw {
  font-size: 18px;
  letter-spacing: 1px;
}

.auth-points {
  display: grid;
  gap: 9px;
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
}
.auth-points li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  color: var(--text-secondary);
}
.auth-points li::before {
  content: '\2713';
  flex: none;
  display: grid;
  place-items: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--brand-blue-primary);
  color: #fff;
  font-size: 11px;
}

/* What the application asks for. Deliberately quieter than the list above it:
   this is reference, read once by somebody deciding whether to start. */
.auth-need {
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.55);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary);
}
.auth-need b {
  display: block;
  margin-bottom: 7px;
  color: var(--text-primary);
}
.auth-need ul {
  display: grid;
  gap: 5px;
  margin: 0;
  padding-inline-start: 18px;
}

.auth-secure {
  display: flex;
  gap: 11px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 46ch;
}
.auth-secure svg { flex: none; margin-top: 2px; color: var(--brand-blue-primary); }
.auth-secure b { display: block; color: var(--text-primary); }

/* the offer strip along the bottom, and the brand rule under it */
.auth-promo {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 18px;
  padding: 15px clamp(20px, 5vw, 60px);
  background: var(--brand-navy-dark);
  color: var(--text-on-dark);
  font-size: 14.5px;
}
.auth-promo .btn-primary { margin: 0; min-height: 40px; }
.auth-accent { position: relative; z-index: 2; height: 4px; background: var(--brand-blue-primary); }

/* the test-user panel is on a light surface here, not the navy one */
.auth-page .creds {
  border-color: var(--border-soft);
  background: var(--bg-muted);
  color: var(--text-secondary);
  backdrop-filter: none;
}
.auth-page .creds > summary { color: var(--text-primary); }
.auth-page .creds b { color: var(--text-primary); }

@media (max-width: 900px) {
  .auth-cols { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  /* Portrait: the picture is a band across the top, so its side and top edges
     are the screen's own and only the lower one is a contour of ours. It gets
     the same treatment as the desktop edges — a fade, not a cut — and one
     layer is enough here, so no compositing is involved. */
  /* Portrait has no side column, so the aside stops being positioned and just
     falls into the page under the sign-in card. Its picture comes off — the
     band across the top is already showing her. */
  .auth-page .auth-aside {
    position: static;
    display: block;
    width: auto;
    padding: 4px 20px 28px;
  }
  /* The band across the top already shows her here, so the aside's copy of the
     picture comes off — and the arch has to go with it, or it is left standing
     as an empty grey shape framing nothing. */
  .auth-page .aside-photo,
  .auth-page .aside-arch { display: none; }
  .auth-page .aside-head { text-align: start; margin-bottom: 14px; }
  .auth-page .auth-photo {
    display: block;
    inset: 0;
    /* `width: min(560px, 34vw)` is the desktop column reservation. Left on, it
       squeezed the band to 34% of the screen and the picture showed as a strip
       down the left edge. The band spans the full width here. */
    width: auto;
    /* The desktop rule shapes the box to the picture. Here the box is the band
       across the top of the screen, so both the derived height and the auto
       margins that centre it have to come back off. */
    height: var(--m-cut-left);
    margin-block: 0;
    background-size: cover;
    background-position: 50% 26%;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 58%, transparent 100%);
    -webkit-mask-composite: source-over;
    mask-composite: add;
  }
  .auth-page .auth-scene::after {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0.92) 34%, rgba(255, 255, 255, 0.98) 100%);
  }
  .auth-page .auth-body, .auth-page .auth-col { display: block; }
  /* The desktop rule reserves room for the photo column with
     `calc(100vw - 34vw - 150px)`. On a 390px phone that leaves 107px and the
     whole page renders as one crushed strip — there is no photo column here,
     so the reservation has to come off. */
  .auth-page .auth-col { max-width: none; }
  .auth-promo { justify-content: flex-start; text-align: start; }
}

/* -------------------------------------------------- registration screen -- */

.reg-page {
  /* The hero column is centred, so the cut runs across the band rather than
     down it — otherwise the rim would slice through the heading. */
  --r-cut-left: 96%;
  --r-cut-right: 74%;
  --reg-band: 300px;
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  background: var(--bg-app);
  color: var(--text-primary);
}
/* here the scenery is a hero band rather than the whole page */
.reg-band {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--reg-band);
  background: linear-gradient(155deg, var(--base-top) 0%, var(--base-mid) 52%, var(--base-bottom) 100%);
}
.reg-page .auth-scene,
.reg-page .auth-rim { bottom: auto; height: var(--reg-band); }
.reg-page .auth-scene {
  clip-path: polygon(0 0, 100% 0, 100% var(--r-cut-right), 0 var(--r-cut-left));
}
.reg-page .auth-scene::after {
  background:
    linear-gradient(90deg, rgba(4, 24, 46, 0.74) 0%, rgba(4, 24, 46, 0.44) 56%, rgba(4, 24, 46, 0.2) 100%),
    linear-gradient(180deg, rgba(4, 24, 46, 0.5) 0%, rgba(4, 24, 46, 0.3) 60%, rgba(4, 24, 46, 0.12) 100%);
}
.reg-page .auth-rim {
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.16) 100%);
  clip-path: polygon(
    0 var(--r-cut-left),
    100% var(--r-cut-right),
    100% calc(var(--r-cut-right) + 2px),
    0 calc(var(--r-cut-left) + 2px));
}
[dir="rtl"] .reg-page .auth-scene {
  clip-path: polygon(0 0, 100% 0, 100% var(--r-cut-left), 0 var(--r-cut-right));
}
[dir="rtl"] .reg-page .auth-scene::after {
  background:
    linear-gradient(270deg, rgba(4, 24, 46, 0.74) 0%, rgba(4, 24, 46, 0.44) 56%, rgba(4, 24, 46, 0.2) 100%),
    linear-gradient(180deg, rgba(4, 24, 46, 0.5) 0%, rgba(4, 24, 46, 0.3) 60%, rgba(4, 24, 46, 0.12) 100%);
}
[dir="rtl"] .reg-page .auth-rim {
  background: linear-gradient(270deg, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0.16) 100%);
  clip-path: polygon(
    0 var(--r-cut-right),
    100% var(--r-cut-left),
    100% calc(var(--r-cut-left) + 2px),
    0 calc(var(--r-cut-right) + 2px));
}

@media (min-width: 621px) {
  /* Same idea on the registration band: full width would magnify the photo
     2.6x, so it takes the right side and feathers into the gradient the hero
     text sits on. */
  .reg-page .auth-photo {
    inset: 0 0 0 58%;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 24%, #000 100%);
    mask-image: linear-gradient(90deg, transparent 0%, #000 24%, #000 100%);
  }
  [dir="rtl"] .reg-page .auth-photo {
    inset: 0 58% 0 0;
    -webkit-mask-image: linear-gradient(270deg, transparent 0%, #000 24%, #000 100%);
    mask-image: linear-gradient(270deg, transparent 0%, #000 24%, #000 100%);
  }
}

.reg-shell {
  position: relative;
  z-index: 2;
  max-width: 780px;
  margin: 0 auto;
  padding: clamp(18px, 2.6vw, 28px) clamp(16px, 4vw, 28px) 48px;
}

.reg-top {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin-bottom: 18px;
}
.reg-top .brand { margin-bottom: 0; }
.reg-page .brand-name { color: var(--text-on-dark); }
.reg-page .brand-sub { color: rgba(255, 255, 255, 0.62); }
.reg-page .brand-mark {
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.32);
}
.reg-top .auth-lang select { min-height: 32px; padding: 5px 9px; }
.reg-top a {
  color: var(--text-on-dark);
  font-size: 13px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.reg-hero { margin-bottom: 88px; color: var(--text-on-dark); }
.reg-hero h1 {
  margin-bottom: 6px;
  color: var(--text-on-dark);
  font-size: clamp(24px, 3vw, 31px);
}
.reg-hero p { margin: 0; max-width: 56ch; font-size: 14px; color: rgba(255, 255, 255, 0.78); }

.reg-section {
  margin: 0 0 16px;
  padding: 20px 22px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
}
.reg-section > header { display: flex; align-items: center; gap: 11px; margin-bottom: 16px; }
.reg-section > header h2 { margin: 0; font-size: 16px; }
.reg-section > header .muted { margin: 2px 0 0; font-size: 12px; }
.reg-step {
  display: grid; place-items: center;
  flex: none;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--brand-blue-primary);
  color: var(--text-on-dark);
  font-size: 12px; font-weight: 700;
}
.reg-section[hidden] { display: none; }

.reg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 16px; }
.reg-grid .full { grid-column: 1 / -1; }
.reg-grid label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px; font-weight: 600;
  color: var(--text-secondary);
}
.reg-grid input, .reg-grid select { width: 100%; margin: 0; min-height: 40px; }

.reg-actions {
  display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border-soft);
}
.reg-actions button { margin: 0; }
.reg-actions.plain { margin-top: 14px; padding-top: 0; border-top: none; }

.reg-note {
  margin-bottom: 16px;
  padding: 10px 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-muted);
  font-size: 12px;
  color: var(--text-secondary);
}
.reg-msg { font-size: 12.5px; font-weight: 600; color: var(--accent-red); }
.reg-msg.ok { color: var(--accent-green); }
.reg-check {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 500;
  color: var(--text-secondary);
}
.reg-check input { min-height: auto; margin: 0; }
.reg-code { width: 110px !important; letter-spacing: 3px; font-variant-numeric: tabular-nums; }
.reg-foot { margin-top: 22px; font-size: 11.5px; color: var(--text-muted); text-align: center; }

@media (max-width: 620px) {
  .reg-page { --reg-band: 276px; }
  .reg-grid { grid-template-columns: minmax(0, 1fr); }
  .reg-section { padding: 16px 15px; }
  .reg-top { flex-wrap: wrap; gap: 10px; }
}

/* register / other standalone pages */
.plain-page { max-width: 820px; margin: 0 auto; padding: 28px 20px 56px; }
fieldset {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-card);
  padding: 16px 18px;
  margin: 0 0 16px 0;
}
legend { font-weight: 600; font-size: 13px; color: var(--text-secondary); padding: 0 6px; }

/* ------------------------------------------------------------- motion --- */

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.animate-page-entry { animation: fadeInUp 350ms var(--ease-out) both; }
/* the auth shells are full-height, so sliding them would push a scrollbar */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.auth-shell.animate-page-entry,
.reg-shell.animate-page-entry { animation-name: fadeIn; }
#main > * { animation: fadeInUp 350ms var(--ease-out) both; }
#main > *:nth-child(1) { animation-delay: 0ms; }
#main > *:nth-child(2) { animation-delay: 40ms; }
#main > *:nth-child(3) { animation-delay: 80ms; }
#main > *:nth-child(4) { animation-delay: 120ms; }
#main > *:nth-child(5) { animation-delay: 160ms; }
#main > *:nth-child(n+6) { animation-delay: 200ms; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  button:hover, .actions a:hover, .tile:hover { transform: none; }
}

/* --------------------------------------------------------- responsive --- */

@media (max-width: 900px) {
  #sidebar {
    position: static;
    width: auto;
    border-right: none;
    border-bottom: 1px solid var(--border-soft);
    padding: 14px 16px;
  }
  #sidebar nav {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 8px;
    padding-bottom: 4px;
  }
  #sidebar nav a { scroll-snap-align: center; white-space: nowrap; border: 1px solid var(--border-soft); }
  #sidebar nav a.active { border-color: var(--brand-blue-primary); }
  #sidebar .who {
    margin-top: 12px;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
  }
  #sidebar .who select { width: auto; }
  #main { margin-left: 0; padding: 16px; }
  /* .client-area #main is the more specific selector, so its centring gutter
     would beat the 16px shorthand above and widen the phone margin to 32px.
     There is no sidebar and no spare width to give away here, so it comes off. */
  .client-area #main { padding-inline: 16px; }
}

/* ------------------------------------------------- multi-step transfer -- */
/* A transfer is a decision made in stages, so it is presented in stages: the
   step list is the only place the customer can see where they are, and it is
   plain text and rules rather than a progress bar, to match the rest. */
.steps {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--border-soft);
}
.steps li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 18px 10px 0;
  margin-inline-end: 18px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.steps-n {
  display: grid;
  place-items: center;
  width: 20px; height: 20px;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.steps li.is-current { color: var(--text-primary); }
.steps li.is-current .steps-n {
  background: var(--brand-navy-hero);
  border-color: var(--brand-navy-hero);
  color: var(--text-on-dark);
}
.steps li.is-done { color: var(--text-secondary); }
.steps li.is-done .steps-n { border-color: var(--silver-strong); color: var(--text-secondary); }

/* the two method tiles on step one */
.choice-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.choice {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 0;
  margin: 0;
  padding: 16px;
  text-align: start;
  background: var(--bg-app);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  color: var(--text-primary);
}
.choice:hover { border-color: var(--silver-strong); background: var(--bg-muted); }
.choice-title { font-size: 14px; font-weight: 700; }
.choice-desc { font-size: 12.5px; font-weight: 400; color: var(--text-secondary); white-space: normal; }

/* the review and receipt list */
.kv {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 0;
  margin: 0 0 16px;
}
.kv dt, .kv dd {
  margin: 0;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-soft);
  font-size: 13px;
}
.kv dt { color: var(--text-secondary); padding-inline-end: 24px; }
.kv dd { text-align: end; }
.kv .kv-strong { font-weight: 700; color: var(--text-primary); }

.step-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 4px; }
.step-actions .btn, .step-actions button { margin: 0; }

@media (max-width: 560px) {
  .steps li { padding-inline-end: 10px; margin-inline-end: 10px; font-size: 11px; }
  .kv { grid-template-columns: minmax(0, 1fr); }
  .kv dt { padding-bottom: 0; border-bottom: 0; }
  .kv dd { text-align: start; padding-top: 2px; }
}

/* ------------------------------------------------------------- offers -- */
/* The five pictures come in at different shapes — a square badge, a 3:2 photo,
   a wide banner — so the card fixes the frame and crops to it. Without that the
   grid's rows tear as each card takes the height its own picture wants. */
.offer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.offer {
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.offer img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  margin: 0;
  border-radius: 0;
  background: var(--bg-muted);
}
.offer-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  padding: 16px;
}
.offer-body h3 { margin: 0; font-size: 15px; letter-spacing: -0.012em; }
.offer-body p { margin: 0; flex: 1; font-size: 13px; color: var(--text-secondary); }
.offer-body button { align-self: flex-start; margin: 6px 0 0; }

/* the same picture again at the top of the application, given more room */
.offer-hero {
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: var(--radius-md);
  margin-bottom: 14px;
}
.apply-done-msg { margin: 14px 0 18px; font-size: 14px; max-width: 60ch; }

/* ---------------------------------------------------------------- logo -- */
/* The supplied artwork is padded symmetrically inside its canvas — the crest
   and wordmark occupy 373x295 of a 676x369 PNG — so the box is sized for the
   whole file and the visible mark lands smaller than the box implies. The
   background is genuinely transparent, so it sits straight on the cream. */
.brand-logo-block {
  display: block;
  margin-bottom: 18px;
}
/* Sized for a SQUARE mark. The previous artwork was a 676x369 wordmark, aspect
   1.83, and every number here was chosen against it — including a negative left
   margin that cancelled the wordmark's own generous internal padding. The
   current mark is 256x256 and effectively edge to edge (7px of transparent
   border on a 256px canvas, measured), so those pulls now drag it past the
   edge instead of onto it, and the widths would make the header half as tall
   again.

   The widths below are the OLD RENDERED HEIGHTS: a 176px-wide wordmark stood
   about 96px tall, so a square mark is 88px wide to occupy the same band. That
   keeps every header the height it was designed around. If the mark wants to be
   larger or smaller, these four numbers are the only ones to change. */
.brand-logo {
  display: block;
  width: 100%;
  max-width: 88px;
  height: auto;
  margin: 0 0 2px;
}
.brand-logo-block .brand-sub {
  padding-inline-start: 4px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 9.5px;
}
/* On the sign-in and registration screens the logo sits on a light surface at
   the top of the page and can afford to be a little larger. */
.auth-top .brand-logo { max-width: 104px; }
@media (max-width: 900px) {
  .brand-logo { max-width: 80px; }
}

/* ==========================================================================
   Sign-in presentation layer
   A deliberately different register from the rest of the product: the app
   inside is restrained navy on cream, this is the shop window. Scoped entirely
   to .auth-page so nothing here reaches the client area or the back office.
   ========================================================================== */

.auth-page {
  background: #F7F8FA;
}

/* The cream halo and paint belong to the old treatment; the scene becomes the
   iridescent field instead. Four soft colour pools rather than one rainbow
   sweep — a single hue rotation reads as a screensaver. */
.auth-page .auth-scene {
  clip-path: none;
  background-image:
    radial-gradient(58% 46% at 76% 26%, rgba(255, 213, 233, 0.55), transparent 68%),
    radial-gradient(52% 42% at 94% 54%, rgba(203, 231, 255, 0.55), transparent 70%),
    radial-gradient(46% 40% at 60% 70%, rgba(212, 253, 233, 0.42), transparent 70%),
    radial-gradient(38% 30% at 86% 84%, rgba(255, 235, 204, 0.48), transparent 70%),
    linear-gradient(180deg, #F9FAFB 0%, #EEF0F4 100%);
  background-color: #F7F8FA;
}
.auth-page .auth-scene::after { background: none; }

/* The rim element is unused on this page, so it carries the light rays that
   fan out of the bottom-left corner instead of adding another wrapper. */
.auth-page .auth-rim {
  display: block;
  inset: auto 0 -6% 0;
  height: 70%;
  clip-path: none;
  pointer-events: none;
  opacity: 0.75;
  background: repeating-linear-gradient(74deg,
    transparent 0 22px,
    rgba(255, 255, 255, 0.85) 22px 27px,
    transparent 27px 58px);
  -webkit-mask-image: radial-gradient(62% 78% at 16% 100%, #000 0%, transparent 72%);
  mask-image: radial-gradient(62% 78% at 16% 100%, #000 0%, transparent 72%);
  filter: blur(7px);
}

/* ---- the arch the photograph stands in ---- */
.aside-stage { position: relative; }
.aside-arch {
  position: absolute;
  /* Flush with the picture horizontally, taller than it at the top. An earlier
     negative side inset made the arch wider — which looked better — but the
     aside sits hard against the right edge of the window, so those few percent
     pushed the document 8px wider than the viewport and the whole page could be
     scrolled sideways. Height is free; width here is not. */
  inset: -10% 0 -3%;
  border-radius: 999px 999px 26px 26px;
  /* Top of the arch is set close to the photograph's own studio grey so its
     background melts into the fill instead of sitting on it as a panel. */
  background: linear-gradient(180deg, #E7E9EB 0%, #F3F4F6 44%, #FAFBFC 100%);
  box-shadow: 0 30px 70px rgba(88, 108, 140, 0.16);
}
/* Iridescent hairline around the arch, drawn as a gradient ring: two masks,
   one clipped to the padding box and one to the border box, excluded from each
   other, which leaves only the 2px edge painted. */
.aside-arch::before {
  content: '';
  position: absolute;
  inset: 0;
  padding: 2px;
  border-radius: inherit;
  background: conic-gradient(from 200deg,
    #FFD9EC, #CFE6FF, #D6FFEA, #FFEBCC, #FFD9EC);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.85;
}
.aside-stage .aside-photo { position: relative; }

.auth-page .aside-head { color: #16233A; font-size: clamp(18px, 1.5vw, 24px); }
.auth-page .aside-list li { color: #465061; }

/* ---- the sign-in card ---- */
/* Was frosted: a translucent gradient with an 18px backdrop blur. Made solid
   on 2026-09-01 with the rest of the restyle. The reason is not only
   consistency — a translucent card over a photograph gives every field a
   different backdrop depending on what happens to be behind it, and the new
   outlined fields need one predictable surface to sit on. The shadow is
   heavier than --shadow-card because this card floats over a photograph
   rather than over a flat page. */
.auth-page .auth-card {
  border: 1px solid transparent;
  border-radius: var(--radius-lg);
  background: var(--bg-card);
  box-shadow: 0 18px 48px rgba(18, 35, 58, 0.24), 0 2px 8px rgba(18, 35, 58, 0.10);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.auth-page .auth-card h2 { color: var(--text-primary); }
.auth-page .auth-card input[type="email"],
.auth-page .auth-card input[type="password"],
.auth-page .auth-card input[type="text"] {
  border-radius: var(--radius-sm);
  border-color: var(--silver-strong);
  background: var(--bg-card);
  min-height: 48px;
  font-size: 14px;
}

/* Primary action: a solid navy block, full width, the one dark thing on a pale
   page so there is never a question about where to click. */
.auth-page .auth-card button[type="submit"] {
  width: 100%;
  margin: 6px 0 0;
  padding: 14px 16px;
  min-height: 48px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--brand-blue-primary);
  color: var(--text-on-dark);
  font-size: 14px;
  box-shadow: var(--shadow-card);
}
.auth-page .auth-card button[type="submit"]:hover {
  background: var(--brand-blue-hover);
  box-shadow: var(--shadow-hover);
}
.auth-page .auth-card .btn-ghost {
  width: 100%;
  margin: 0;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.6);
  border-color: rgba(120, 132, 155, 0.35);
}

/* the panel beside the form sits on the same pale field, so it stays plain */
.auth-page .auth-links .creds,
.auth-page .auth-secure {
  background: rgba(255, 255, 255, 0.72);
  border-radius: 14px;
}

/* Backstop: body already hides its own horizontal overflow, but the document
   element does not, so anything that does escape still scrolls the page.
   `clip` rather than `hidden` because it does not create a scroll container. */
html:has(body.auth-page) { overflow-x: clip; }

/* -------------------------------------------- application form furniture -- */
/* Two columns on a wide screen, one on a narrow one. A bank application asks a
   lot of short questions, and a single column of them turns every step into a
   scroll. */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0 18px;
  margin-bottom: 4px;
}
.form-grid .field-wide { grid-column: 1 / -1; }

/* ---- identity document capture ---- */
.doc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin: 14px 0 6px;
}
.doc-slot { display: flex; flex-direction: column; gap: 8px; }
.doc-slot-label {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.doc-drop {
  display: grid;
  place-items: center;
  aspect-ratio: 8 / 5;          /* the shape of a card or a passport page */
  overflow: hidden;
  border: 1px dashed var(--silver-strong);
  border-radius: var(--radius-md);
  background: var(--bg-muted);
  cursor: pointer;
}
.doc-drop:hover { border-color: var(--brand-blue-primary); }
.doc-preview { width: 100%; height: 100%; object-fit: cover; }
.doc-hint { font-size: 12.5px; color: var(--text-secondary); }
.doc-slot .btn-ghost { align-self: flex-start; margin: 0; }

/* ---- agreement and signature ---- */
.agreement-box {
  max-height: 240px;
  overflow-y: auto;
  padding: 16px 18px;
  margin-bottom: 14px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--bg-app);
}
.agreement-box h4 { margin: 0 0 10px; font-size: 13px; }
.agreement-box p {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 78ch;
}
.sign-wrap { position: relative; margin-bottom: 10px; }
.sign-pad {
  display: block;
  width: 100%;
  max-width: 560px;
  aspect-ratio: 3 / 1;
  border: 1px solid var(--silver-strong);
  border-radius: var(--radius-md);
  background: #FFFFFF;
  /* Without this a drag on a touch screen scrolls the page instead of drawing. */
  touch-action: none;
  cursor: crosshair;
}
.sign-baseline {
  position: absolute;
  left: 24px;
  width: min(512px, calc(100% - 48px));
  bottom: 22%;
  border-bottom: 1px solid var(--border-strong);
  pointer-events: none;
}

/* ==================================================================== chat */
/* Two panes filling the height the shell gives them: conversations on the
   left, the open one on the right. The message list is the only thing that
   scrolls, so the composer stays put while the history moves under it. */
.chat {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: 16px;
  /* the shell's own padding is 28px top and 56px bottom */
  height: calc(100vh - 84px - 74px);
  min-height: 460px;
}

.chat-list, .chat-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;              /* lets the inner scroller actually scroll */
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
}

.chat-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 14px 12px;
  border-bottom: 1px solid var(--border-soft);
}
.chat-list-head h3 {
  margin: 0;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.chat-list-head button { margin: 0; padding: 6px 10px; min-height: 30px; font-size: 12px; }

.chat-threads { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; }
.chat-none { padding: 16px 8px; font-size: 13px; color: var(--text-secondary); }

.chat-thread {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 0 0 4px;
  padding: 10px;
  text-align: start;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
}
.chat-thread:hover { background: var(--bg-muted); border-color: var(--border-soft); }
.chat-thread.is-active { background: var(--bg-muted); border-color: var(--silver-strong); }
.chat-thread-main { flex: 1; min-width: 0; }
.chat-thread-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.chat-thread-top b { font-size: 13px; font-weight: 600; }
.chat-thread-top span { flex: none; font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.chat-thread-preview {
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-unread {
  flex: none;
  display: grid;
  place-items: center;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--brand-blue-primary);
  color: var(--text-on-dark);
  font-size: 11px;
  font-weight: 700;
}

/* ---- the open conversation ---- */
.chat-pane { position: relative; }
.chat-empty, .chat-new, .chat-open { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.chat-empty { align-items: center; justify-content: center; color: var(--text-secondary); font-size: 13px; }
.chat-new-body { padding: 16px; overflow-y: auto; }
.chat-new-body textarea { width: 100%; }

.chat-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-soft);
}
.chat-head-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-head-main b { font-size: 14px; }
.chat-head-sub { font-size: 12px; color: var(--text-secondary); }
.chat-back { display: none; margin: 0; padding: 4px 8px; min-height: 0; }

.chat-avatar {
  flex: none;
  width: 38px; height: 38px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-muted);
}
.chat-avatar.sm { width: 30px; height: 30px; }
.chat-avatar.is-placeholder { border: 1px dashed var(--border-strong); }

.chat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 14px;
  background: var(--bg-app);
}
.chat-day {
  margin: 6px 0 14px;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.chat-msg { display: flex; align-items: flex-end; gap: 8px; margin-bottom: 12px; }
.chat-msg.is-mine { flex-direction: row-reverse; }
.chat-bubble {
  max-width: min(72%, 62ch);
  padding: 9px 12px 7px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--bg-card);
}
.chat-msg.is-mine .chat-bubble {
  background: var(--brand-navy-hero);
  border-color: var(--brand-navy-hero);
  color: var(--text-on-dark);
}
.chat-who { font-size: 11px; font-weight: 700; margin-bottom: 3px; color: var(--text-secondary); }
.chat-msg.is-mine .chat-who { color: rgba(255, 255, 255, 0.72); }
.chat-text { font-size: 13.5px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat-time { margin-top: 4px; font-size: 10.5px; color: var(--text-muted); text-align: end; font-variant-numeric: tabular-nums; }
.chat-msg.is-mine .chat-time { color: rgba(255, 255, 255, 0.6); }

/* a file inside a bubble */
.chat-file {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  margin: 6px 0 0;
  padding: 7px 9px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-app);
  color: var(--text-primary);
  font-size: 12px;
  text-align: start;
  cursor: pointer;
}
.chat-file:hover { border-color: var(--brand-blue-primary); background: var(--bg-muted); }
.chat-file span:nth-child(2) { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-file span:last-child { flex: none; color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ---- composer ---- */
.chat-composer { border-top: 1px solid var(--border-soft); padding: 10px 12px 12px; }
.chat-composer-row { display: flex; align-items: flex-end; gap: 8px; }
.chat-composer-row textarea {
  flex: 1;
  min-height: 38px;
  max-height: 160px;
  margin: 0;
  resize: none;
  line-height: 1.45;
}
.chat-composer-row .btn-primary { margin: 0; }
.chat-clip {
  flex: none;
  margin: 0;
  padding: 0;
  width: 38px;
  min-height: 38px;
  font-size: 16px;
  line-height: 1;
}
.chat-attach-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.chat-pending {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 6px 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--bg-muted);
  font-size: 11.5px;
}
.chat-pending span:last-of-type { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.chat-pending-x {
  margin: 0; padding: 0;
  width: 18px; min-height: 18px;
  border: 0; border-radius: 50%;
  background: none;
  font-size: 14px; line-height: 1;
  color: var(--text-secondary);
}
.chat-pending-x:hover { background: var(--border-strong); color: var(--text-primary); }
.chat-closed-note {
  padding: 12px 14px;
  border-top: 1px solid var(--border-soft);
  font-size: 12.5px;
  color: var(--text-secondary);
}

/* One pane at a time on a phone: the list until something is opened, then the
   conversation, with the arrow in its header going back. */
@media (max-width: 860px) {
  .chat {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    min-height: 0;
  }
  .chat-list { max-height: 60vh; }
  .chat-pane { min-height: 62vh; }
  .chat.is-open .chat-list { display: none; }
  .chat:not(.is-open) .chat-pane { display: none; }
  .chat-back { display: inline-block; }
  .chat-bubble { max-width: 86%; }
}

/* ------------------------------------------------- sign-in on a phone ---- */
@media (max-width: 900px) {
  /* The crest sat across her face. Smaller, and pulled hard left — the artwork
     occupies only the middle 55% of its PNG (151px of transparent padding each
     side of 676), so a plain `margin-left: 0` still leaves the visible mark
     floating inward. The negative margin is that padding, scaled. */
  .auth-top .brand {
    /* without this the header's flex squeezes the logo to whatever the language
       picker leaves over, and the mark shrinks below legibility */
    flex: none;
  }
  .auth-top .brand-logo {
    width: 68px;
    max-width: none;
    /* was -28px, cancelling the old wordmark's internal padding; the square
       mark has none to cancel */
    margin-inline-start: 0;
    margin-bottom: 0;
  }

  /* The greeting and the heading were navy text lying over her hair, which is
     close to unreadable. They join the sign-in card instead.

     They are siblings of the card, not children of it, so rather than moving
     them in the markup the two are drawn as one surface: the welcome block
     takes the top corners and border, the card gives them up. Their side
     padding has to match the card's or the seam shows. */
  .auth-page .auth-welcome {
    margin: 0;
    padding: 22px 26px 0;
    border: 1px solid rgba(255, 255, 255, 0.9);
    border-bottom: 0;
    border-radius: 16px 16px 0 0;
    background: linear-gradient(150deg, rgba(255, 255, 255, 0.84), rgba(246, 244, 250, 0.66));
    -webkit-backdrop-filter: blur(18px) saturate(1.25);
    backdrop-filter: blur(18px) saturate(1.25);
  }
  .auth-page .auth-welcome h1 { font-size: 22px; }
  .auth-page .auth-cols { margin-top: 0; }
  .auth-page .auth-card {
    border-top: 0;
    border-start-start-radius: 0;
    border-start-end-radius: 0;
    padding-top: 18px;
  }
}

/* ---- restricted account ----------------------------------------------------
   Shown on Cards, Loans and Investments while a registration is still waiting
   to be reviewed. It states account state rather than reporting an error, so
   it is amber and sits at the top of the section instead of beside a control.
   role="status" rather than "alert": nothing the customer just did caused it. */
.restricted-note {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin: 0 0 22px;
  padding: 14px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-left: 4px solid var(--accent-amber);
  border-radius: var(--radius-md);
}
.restricted-mark {
  flex: none;
  width: 20px; height: 20px; margin-top: 1px;
  border-radius: 50%;
  background: var(--accent-amber);
  color: var(--bg-card);
  font-size: 13px; font-weight: 700; line-height: 20px;
  text-align: center;
}
.restricted-text { min-width: 0; }
.restricted-title {
  font-size: 14px; font-weight: 600;
  color: var(--text-primary);
}
.restricted-detail {
  margin-top: 4px;
  font-size: 13px; line-height: 1.5;
  color: var(--text-secondary);
}

/* A locked control stays visible so the section reads as closed rather than
   empty, but it takes no clicks and no longer invites one. */
.is-locked,
.is-locked:hover {
  opacity: .5;
  cursor: not-allowed;
  border-color: var(--border-soft);
  background: var(--bg-muted);
  color: var(--text-muted);
}

/* ---- back office: chat reply --------------------------------------------
   Stacked rather than laid out as a row: the reply is the wide element here
   and the buttons sit under it, so a long message stays fully readable. */
.bo-reply { display: flex; flex-direction: column; gap: 10px; }
.bo-reply textarea {
  width: 100%;
  margin: 0;
  min-height: 96px;
  max-height: 420px;
  resize: vertical;
  line-height: 1.5;
}
.bo-reply-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.bo-reply-actions button { margin: 0; min-height: 38px; }

/* ---- transfers held for review ------------------------------------------
   Amber, like every other "waiting on someone" state in here: the money has
   left but has not arrived, which is neither a success nor a failure. */
.pill.in_review { background: #FFFBEB; border-color: #FDE68A; color: #B45309; }
.pill.approved { background: #ECFDF5; border-color: #A7F3D0; color: #047857; }

#pendingList .feed-item { align-items: flex-start; }
#pendingList .pill { margin-left: 6px; }
.pending-sub {
  margin-top: 2px;
  font-size: 12px;
  color: var(--text-muted);
}

/* The beneficiary bank details stacked into one cell of the review queue —
   four columns of mostly-empty address would push the table off the page. */
.bo-bank-cell { font-size: 12px; line-height: 1.45; color: var(--text-secondary); }
.bo-bank-cell div:first-child { font-weight: 600; color: var(--text-primary); }
.bo-sub { font-size: 12px; color: var(--text-muted); }

/* ---- deposits ------------------------------------------------------------
   The details and the QR sit side by side where there is room and stack when
   there is not; the code keeps a fixed size either way, because a QR scaled
   down past its module size stops being scannable. */
.deposit-body {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
}
.deposit-body .kv { flex: 1 1 320px; min-width: 0; margin: 0; }
.deposit-qr {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px;
  background: #FFFFFF;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
}
/* white behind the modules regardless of the surrounding surface, and never
   smaller than the scanners can resolve */
.deposit-qr img { display: block; width: 200px; height: 200px; background: #FFFFFF; }
.deposit-qr-cap { font-size: 12px; color: var(--text-muted); }

/* An IBAN or a wallet address is read a character at a time when it is checked,
   so it gets a monospaced face and is allowed to wrap anywhere. */
.mono-value {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  word-break: break-all;
}
.copy-btn {
  margin: 0 0 0 10px;
  padding: 2px 10px;
  min-height: 0;
  font-size: 12px;
  vertical-align: middle;
}
.kv-hint { font-size: 12px; color: var(--text-muted); }

/* ---- sending to a wallet -------------------------------------------------
   Coin sent to a wrong address is gone, so the warning sits above the field
   rather than below it, where it would be read only after the mistake. */
.wallet-warning {
  margin: 0 0 14px;
  padding: 10px 12px;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-left: 4px solid var(--accent-amber);
  border-radius: var(--radius-md);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
}
.wallet-row { display: flex; gap: 8px; align-items: stretch; }
.wallet-row input {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}
.wallet-row button { flex: none; margin: 0; }
.wallet-row button:disabled { opacity: .5; cursor: not-allowed; }

/* The camera view. Fixed over everything, because a half-visible viewfinder
   behind the page is worse than useless for lining up a code. */
.scan-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(11, 22, 38, 0.82);
}
.scan-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: min(420px, 100%);
  padding: 18px;
  background: var(--bg-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  text-align: center;
}
.scan-box p { margin: 0; font-size: 14px; color: var(--text-secondary); }
.scan-box video {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: #000;
  border-radius: var(--radius-md);
}
.scan-box button { margin: 0; }

/* ==========================================================================
   Client patterns lifted from the reference screenshots — hero band, account
   tile strip, quick-action discs, merchant transaction rows, contact card,
   status pills, sheet modal, legal footer.

   These are the *features* of that reference, not its styling. The register
   stays the one settled on 27 Aug: flat surfaces, 4px radii, no card shadows,
   no hover lift, cream and navy, silver rules. Where the reference floats a
   white card on a shadow, this separates with a 1px silver rule instead.
   ========================================================================== */

/* Gold, from the crest. 6.54:1 on --brand-navy-hero, so it may carry text on
   navy — but only 1.9:1 on the cream page, so on light surfaces it is a rule
   or a marker and never a letter. */
:root {
  --gold: #C9A227;
  --gold-dim: rgba(201, 162, 39, 0.35);
}

/* ------------------------------------------------------- page hero band -- */
/* Same construction as the sign-in scene: a painted sky, the photograph
   clipped to a wedge on the trailing edge, a lit rim along the cut. Reduced
   to a band, and re-declared locally because the sign-in values are scoped to
   .auth-page. */
/* The band across the top of every client and back office page.

   It carries a panoramic photograph chosen for the visitor's own part of the
   day — set by data-tod on <body> from the server's instant read in the
   browser's timezone. The sign in and registration pages are deliberately NOT
   this component: they keep their own single photograph, scoped to .auth-page.

   The photographs are ~2900x330 banners, so unlike the portrait source this
   band was first built for they span it end to end rather than being cropped
   into a diagonal wedge on the right. */
.page-hero {
  --cut-top: 62%;
  --cut-bottom: 40%;
  --scene-photo: url("/img/scene/coast-day.jpg?v=202610261955");
  --scene-paint: linear-gradient(180deg, #BFDCEF 0%, #D8E7F2 38%, #E7E2D6 66%, #CBBEAA 100%);
  position: relative;
  overflow: hidden;
  margin-bottom: 18px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: linear-gradient(155deg, #04182E 0%, #0A2540 52%, #0E3A63 100%);
  color: var(--text-on-dark);
}
/* No clip-path: a panorama fills the band. The diagonal cut existed to let a
   portrait photograph occupy only the right-hand end. */
.page-hero-scene {
  position: absolute;
  inset: 0;
  background-image: var(--scene-paint);
  background-size: cover;
  background-position: 50% 62%;
}
.page-hero-photo {
  position: absolute;
  inset: 0;
  background-image: var(--scene-photo);
  background-repeat: no-repeat;
  background-position: 50% 50%;
  background-size: cover;
}
.page-hero-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  /* The scrim. It paints after .page-hero-photo inside the same box, so it
     covers the photograph and keeps the heading legible whatever the picture
     is doing behind it — a bright noon shot and a dark night one both end up
     readable. Carried further across than before, because the photograph now
     spans the whole band rather than only its right-hand end. */
  background:
    linear-gradient(100deg, rgba(4, 24, 46, 0.94) 0%, rgba(10, 37, 64, 0.74) 34%, rgba(10, 37, 64, 0.18) 68%, rgba(10, 37, 64, 0.08) 100%),
    linear-gradient(180deg, rgba(4, 24, 46, 0.3) 0%, rgba(4, 24, 46, 0.05) 45%, rgba(4, 24, 46, 0.45) 100%);
}
/* Mirrored right-to-left so the text still sits over the dark end. Flipping a
   landscape costs nothing; flipping a portrait of a person would not. */
[dir="rtl"] .page-hero-scene { transform: scaleX(-1); }
/* The rim drew the lit edge of the diagonal cut. There is no diagonal any
   more, so it draws nothing — kept as an empty box rather than removed from
   pageHero(), which both shells call. */
.page-hero-rim { display: none; }
/* One photograph per part of the visitor's own day. Scoped to .page-hero so it
   cannot reach the sign in and registration pages, which keep their own single
   picture under .auth-page. The default above is the morning one, so a page
   that somehow renders before data-tod is set shows a photograph rather than
   an empty band. */
body[data-tod="morning"] .page-hero   { --scene-photo: url("/img/scene/coast-morning.jpg?v=202610261955"); }
body[data-tod="afternoon"] .page-hero { --scene-photo: url("/img/scene/coast-day.jpg?v=202610261955"); }
body[data-tod="evening"] .page-hero   { --scene-photo: url("/img/scene/coast-evening.jpg?v=202610261955"); }
body[data-tod="night"] .page-hero     { --scene-photo: url("/img/scene/coast-night.jpg?v=202610261955"); }

.page-hero-body {
  position: relative;
  z-index: 2;
  padding: 26px 28px;
  max-width: 56%;
}
.page-hero-body h2 {
  margin: 0 0 3px;
  color: var(--text-on-dark);
  font-size: 24px;
  letter-spacing: -0.4px;
}
.page-hero-eyebrow {
  margin: 0 0 10px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--gold);
}
.page-hero-sub { margin: 0; font-size: 12.5px; color: rgba(255, 255, 255, 0.72); }

/* A .dash-head promoted into the band by renderShell keeps its own markup, so
   its heading and muted line are re-coloured for the navy rather than rebuilt. */
.page-hero-body .dash-head { margin-bottom: 0; }
.page-hero-body .dash-head h2 {
  margin: 0 0 3px;
  color: var(--text-on-dark);
  font-size: 24px;
  letter-spacing: -0.4px;
}
.page-hero-body .muted,
.page-hero-body .dash-head p { color: rgba(255, 255, 255, 0.72); }

@media (max-width: 900px) {
  .page-hero { --cut-top: 84%; --cut-bottom: 68%; }
  .page-hero-body { max-width: 100%; padding: 20px; }
  .page-hero-body h2 { font-size: 20px; }
}

/* -------------------------------------------------- account tile strip -- */
/* The reference floats separate filled cards. Here they are one strip divided
   by hairlines: the gap is the container's own colour showing through, so no
   shadow is needed to keep the tiles apart. */
/* The number of accounts varies a lot — two on one customer, eight on another —
   so the strip hugs its tiles instead of dividing the full width between them.
   Stretched to 1fr, two accounts became two 639px slabs of empty navy. Tiles
   keep a fixed footing and wrap onto further rows once they run out of room. */
.tile-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
  margin-bottom: 18px;
}
.acct-tile {
  display: block;
  flex: 0 0 auto;
  min-width: 210px;
  padding: 16px 18px 17px;
  border: 0;
  /* Each tile carries its own corner. An earlier version divided one navy
     block with 1px gaps, which looked right until a ragged last row left a
     wide band of the divider colour showing beside the final tile. */
  border-radius: var(--radius-md);
  font: inherit;
  text-align: start;
  text-decoration: none;
  background: var(--brand-navy-hero);
  color: var(--text-on-dark);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: background 120ms var(--ease-out), box-shadow 150ms var(--ease-out);
}
.acct-tile:hover {
  background: var(--brand-blue-hover);
  box-shadow: var(--shadow-hover);
  text-decoration: none;
}
/* The selected account is marked with a gold rule inset along the bottom
   rather than a raised card, which is how the rest of this interface signals
   the current item. */
.acct-tile[aria-current="true"] {
  background: var(--brand-blue-hover);
  box-shadow: inset 0 -3px 0 var(--gold);
}
.acct-tile-name {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: rgba(255, 255, 255, 0.78);
}
.acct-tile-bal {
  margin-top: 5px;
  font-size: 19px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.3px;
  font-variant-numeric: tabular-nums;
}
.acct-tile-cur { font-size: 11px; font-weight: 600; margin-inline-start: 4px; color: rgba(255, 255, 255, 0.7); }
.acct-tile-foot {
  margin-top: 3px;
  font-size: 10.5px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
}

/* ------------------------------------------------ quick-action discs ---- */
.qa-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-bottom: 22px;
}
.qa {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: 76px;
  text-decoration: none;
  color: var(--text-secondary);
}
.qa:hover { text-decoration: none; color: var(--text-primary); }
.qa-disc {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--silver-strong);
  border-radius: var(--radius-pill);
  background: var(--bg-card);
  color: var(--brand-blue-primary);
  transition: background 120ms var(--ease-out), color 120ms var(--ease-out), border-color 120ms var(--ease-out);
}
.qa:hover .qa-disc {
  background: var(--brand-navy-hero);
  border-color: var(--brand-navy-hero);
  color: var(--text-on-dark);
}
.qa:focus-visible { outline: none; }
.qa:focus-visible .qa-disc { outline: 2px solid var(--brand-blue-primary); outline-offset: 2px; }
.qa-label { font-size: 11.5px; font-weight: 600; text-align: center; line-height: 1.25; }

/* -------------------------------------------- merchant transaction rows -- */
/* The reference lists transactions as merchant rows rather than as a
   four-column table. Kept as rows here, but the amount stays tabular so the
   column still reads down the page. */
.txlist { display: flex; flex-direction: column; }
/* Roomier rows in the retail-app register: the reference gives each line about
   14px of vertical air and lets the hover tint bleed into the panel padding
   rather than stopping at the text column. */
.tx-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 3px 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border-soft);
  text-decoration: none;
  color: inherit;
  border-radius: var(--radius-sm);
}
.tx-row:last-child { border-bottom: 0; }
a.tx-row:hover { text-decoration: none; background: var(--bg-muted); box-shadow: 0 0 0 8px var(--bg-muted); }
.tx-name { font-size: 13.5px; font-weight: 600; }
.tx-meta { grid-column: 1; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.tx-amt {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tx-amt.credit { color: var(--accent-green); }
.tx-empty { padding: 12px 0; color: var(--text-muted); }

/* A transaction row that opens something. Reset to look like the rest of the
   list rather than like a button, since what it is is a row. */
.pending-row {
  width: 100%;
  font: inherit;
  text-align: start;
  background: none;
  border-width: 0 0 1px 0;
  border-radius: 0;
  cursor: pointer;
}
.pending-row:hover { background: var(--bg-muted); box-shadow: 0 0 0 6px var(--bg-muted); }
.pending-row:focus-visible { outline: 2px solid var(--brand-blue-primary); outline-offset: 2px; }
.pending-row .tx-name { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }

/* Search sitting in a section head, as the reference puts it above its
   transaction list. .sec-head is baseline-aligned with its rule hung off
   ::after, so the tools ride in their own box rather than on the heading. */
.sec-head .sec-tools { margin-inline-start: auto; display: flex; align-items: center; gap: 8px; }
.sec-search {
  width: min(200px, 42vw);
  padding: 5px 9px;
  font: inherit;
  font-size: 12px;
  color: var(--text-primary);
  background: var(--bg-card);
  border: 1px solid var(--silver-strong);
  border-radius: var(--radius-sm);
}
.sec-search:focus { outline: 2px solid var(--brand-blue-primary); outline-offset: 1px; border-color: var(--brand-blue-primary); }

/* ------------------------------------------------------- contact card ---- */
.contact-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border-soft);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.contact-act {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 12px 6px;
  background: var(--bg-card);
  color: var(--text-secondary);
  font-size: 11.5px;
  font-weight: 600;
  text-decoration: none;
}
.contact-act:hover { background: var(--bg-muted); color: var(--text-primary); text-decoration: none; }
.contact-act svg { color: var(--brand-blue-primary); }

/* One person you can reach, with the ways to reach them beneath. */
.contact-block { margin-bottom: 14px; }
.contact-who {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 600;
}
.contact-role { font-size: 11.5px; font-weight: 500; color: var(--text-muted); }
/* An email address is long and must not be truncated into uselessness, so the
   cell that carries one is allowed to wrap. */
.contact-act { word-break: break-word; text-align: center; }

/* A row whose right-hand cell holds a control rather than an amount. */
.passkey-row .tx-amt { align-self: center; }

/* ----------------------------------------------------- status pills ------ */
/* Extends the existing set with the states the reference shows on batches and
   on remote deposits. The leading dot is what carries the state for anyone who
   cannot separate the tints. */
.pill.processing, .pill.initiated { background: #FFFBEB; border-color: #FDE68A; color: #8A5A10; }
.pill.accepted, .pill.processed, .pill.ready { background: #ECFDF5; border-color: #A7F3D0; color: #1B6B4A; }
.pill.dot::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-inline-end: 5px;
  border-radius: var(--radius-pill);
  background: currentColor;
  vertical-align: 1px;
}

/* --------------------------------------------------------- sheet modal --- */
/* The reference's centred panel: back chevron, title over a subtitle, a
   summary row of counts, then the rows themselves and dot pagination.
   --shadow-float is the one elevation token this design kept, and it exists
   precisely for things that genuinely float over the page. */
.sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(11, 22, 38, 0.42);
}
.sheet {
  width: min(540px, 100%);
  max-height: min(680px, 88vh);
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-float);
  overflow: hidden;
}
.sheet-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-soft);
}
.sheet-title { text-align: center; }
.sheet-title strong { display: block; font-size: 14px; }
.sheet-title span { display: block; font-size: 11.5px; color: var(--text-muted); }
.sheet-icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
}
.sheet-icon:hover { background: var(--bg-muted); color: var(--text-primary); }
.sheet-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
}
/* The same summary figures outside a sheet — a statement's opening and closing
   balances, a loan's terms. Wraps rather than forcing three across, because a
   statement has six of them and a phone has room for one. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 1px;
  margin-bottom: 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-md);
  background: var(--border-soft);
  overflow: hidden;
}
.stat { padding: 12px 14px; background: var(--bg-card); }
.stat-label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--text-muted);
}
.stat-value {
  margin-top: 4px;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.3px;
  font-variant-numeric: tabular-nums;
}
.sheet-body { overflow-y: auto; padding: 0 16px; }
/* Actions that act on whatever the sheet is showing — repaying the loan you
   just opened, for instance. Kept with the thing they act on, so the amount
   typed can never belong to a different row. */
.sheet-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 14px 0 16px;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
}
.sheet-actions input { width: 130px; }
.sheet-actions .reg-msg { flex-basis: 100%; }
.sheet-foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 12px;
  border-top: 1px solid var(--border-soft);
}
.sheet-dots { display: flex; align-items: center; gap: 7px; }
/* Replaces the dots once there are too many to read. Tabular so the width
   does not jump as the page number changes. */
.sheet-count {
  min-width: 62px;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.sheet-foot .sheet-icon:disabled {
  opacity: 0.32;
  cursor: default;
}
.sheet-foot .sheet-icon:disabled:hover { background: none; color: var(--text-secondary); }
.sheet-dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--border-strong);
  cursor: pointer;
}
.sheet-dot[aria-current="true"] { background: var(--brand-blue-primary); }

/* An account that is frozen or closed still appears in the strip, so this
   says so in words rather than leaving it to the absence of something. */
.acct-warn {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -6px 0 18px;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-inline-start: 3px solid var(--accent-amber);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  font-size: 12.5px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* A field that wants the whole row of its .apply-card — a description, an
   instruction, anything where the value is long and the box should be too.
   Replaces `style="flex: 1 1 100%"` written onto individual fields. */
.field.wide-field { flex: 1 1 100%; }

/* A queue on the back office dashboard: the same disc as a client quick
   action, with the number of things waiting on it. */
.queue-link { position: relative; }
.queue-count {
  position: absolute;
  top: -5px;
  inset-inline-end: -5px;
  min-width: 19px;
  height: 19px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--accent-red);
  color: #FBFBF9;
  font-size: 11px;
  font-weight: 700;
  line-height: 19px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* An empty queue stays on screen, dimmed. Hiding it would leave staff unsure
   whether it was empty or simply not checked. */
.queue-link.is-empty { opacity: 0.45; }
.queue-link.is-empty:hover { opacity: 1; }

/* Each investment account is its own block. It used to be separated from the
   next by an <hr>; the panel border already does that job. */
.invacct { margin-bottom: 16px; }
.invacct .sec-head { margin-top: 18px; }
.invacct .sec-head:first-child { margin-top: 0; }
.invacct-foot { margin-top: 14px; }
/* The asset mark sits inside the row heading, so it needs to line up with the
   text beside it rather than sit on the baseline. */
.asset-row .tx-name, .pending-row .tx-name { display: flex; align-items: center; gap: 7px; }

/* Which account and which period the figures below belong to. */
.stmt-period {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------- legal footer ---- */
.site-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin-top: 28px;
  padding: 14px 18px;
  border-radius: var(--radius-md);
  background: var(--brand-navy-hero);
  color: rgba(255, 255, 255, 0.68);
  font-size: 11.5px;
}
.site-foot a { color: rgba(255, 255, 255, 0.86); }
.site-foot a:hover { color: var(--text-on-dark); }
.site-foot-sep { color: rgba(255, 255, 255, 0.3); }

/* --------------------------------------------- sidebar icons and avatar -- */
#sidebar nav a { display: flex; align-items: center; gap: 9px; }
#sidebar nav a svg { flex: none; opacity: 0.72; }
#sidebar nav a.active svg { opacity: 1; }
#sidebar .who-id { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
#sidebar .who-id .who-name { font-weight: 600; color: var(--text-primary); }
#sidebar .who-id .who-mail {
  font-size: 11px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avatar-disc {
  display: grid;
  place-items: center;
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  background: var(--brand-navy-hero);
  color: var(--gold);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
}

/* ==========================================================================
   Sign-in, converted to the reference composition — 2026-09-01
   Asked for explicitly: "so it will look exactly as the screenshots".
   The reference is a full-bleed photograph with a single centred white card
   and nothing else on the page. What was here instead — an iridescent pastel
   field, light rays, an arch holding a second photograph, a welcome headline
   and a benefits column beside the card — is switched off below rather than
   deleted, so the previous composition is one block away from being restored.

   Two things are deliberately kept that the reference has no room for, because
   removing them would cost function rather than decoration: the "Open an
   account" link (the only route to registration from this page) and the
   language picker. Both are folded under the card instead of beside it.
   ========================================================================== */
body.auth-page .auth-scene {
  clip-path: none;
  /* Scrim first, photograph second. The card is white and the photograph is
     bright at the horizon, so without the wash the card's own shadow does
     nothing and the edge disappears into the sky. */
  /* NOT --scene-photo: that is /img/scene/coast-day.jpg, a 612x408 studio portrait built
     to sit inside the arch, which stretches badly full-bleed. hero/evening.jpg
     is the only clean wide asset in the project — the login-scenery set are
     watermarked Unsplash previews and must not ship. It is a 2928x332
     panorama, so it upscales about 2.4x vertically here and goes soft on a
     large screen. Replace with a properly licensed landscape when one exists. */
  background-image:
    linear-gradient(180deg, rgba(9, 20, 36, 0.34) 0%, rgba(9, 20, 36, 0.22) 45%, rgba(9, 20, 36, 0.40) 100%),
    var(--auth-photo, url('/img/scene/coast-day.jpg?v=202610261955'));
  background-size: cover, cover;
  background-position: 50% 50%, 50% 50%;
  background-repeat: no-repeat, no-repeat;
  background-color: var(--brand-navy-dark);
}
body.auth-page .auth-scene::after { background: none; }

/* Page furniture with no counterpart in the reference. */
body.auth-page .auth-rim,
body.auth-page .auth-aside,
body.auth-page .auth-accent,
body.auth-page .auth-promo,
body.auth-page .auth-welcome,
body.auth-page .auth-need,
body.auth-page .auth-secure { display: none !important; }

/* One centred column, vertically centred in the viewport. */
body.auth-page .auth-shell {
  max-width: none;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 32px 20px;
  grid-template-rows: none;
}
/* .auth-col carried a 646px max-width with no auto margins, which is what held
   the card left of centre once the two columns were stacked. */
body.auth-page .auth-body,
body.auth-page .auth-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: none;
  margin: 0 auto;
}
body.auth-page .auth-cols {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 100%;
}
body.auth-page .auth-card {
  width: 100%;
  max-width: 430px;
  padding: 32px 32px 28px;
}
body.auth-page .auth-links {
  width: 100%;
  max-width: 430px;
  text-align: center;
}
/* The header sits on the photograph, so its type goes white. */
body.auth-page .auth-shell > header,
body.auth-page .brand-logo-block { display: flex; flex-direction: column; align-items: center; gap: 6px; }
body.auth-page .brand-name { color: var(--text-on-dark); }
body.auth-page .brand-sub { color: rgba(255, 255, 255, 0.78); }
body.auth-page .auth-links a { color: var(--text-on-dark); font-weight: 600; }

/* The sign-in photograph follows the same time-of-day rotation as the client
   area's hero, driven by data-tod on <body>. The fallback in the shorthand
   above covers the instant before that attribute is set. */
body.auth-page[data-tod="morning"]   { --auth-photo: url("/img/scene/coast-day.jpg?v=202610261955"); }
body.auth-page[data-tod="afternoon"] { --auth-photo: url("/img/scene/coast-day.jpg?v=202610261955"); }
body.auth-page[data-tod="evening"]   { --auth-photo: url("/img/scene/coast-day.jpg?v=202610261955"); }
body.auth-page[data-tod="night"]     { --auth-photo: url("/img/scene/coast-day.jpg?v=202610261955"); }

/* ==========================================================================
   Green accent — 2026-09-01
   Chosen by the user from the reference, which uses a green emblem and green
   category chips against a navy interface. Navy stays the primary; green is an
   accent for tags, chips, badges and the brand mark. Gold survives only inside
   the crest artwork itself.

   --brand-green is the existing --accent-green value, reused deliberately
   rather than picking a brighter one by eye: it is already measured at 6.1:1
   on white, so it is legible as text and safe as a fill behind white text.
   ========================================================================== */
:root {
  --brand-green: #1B6B4A;
  --brand-green-hover: #155A3E;
  /* Tint pair for chips: 12.9:1 for the text on its own background */
  --brand-green-soft: #E8F5EE;
  --brand-green-line: #A7D8C0;
}

/* The badge mark. The var(--mark-bg, #1B6B4A) inside mark-badge.svg only
   resolves when the file is inlined into the document; loaded through <img>
   it is an isolated document and always takes the fallback. That is fine —
   the fallback is the brand green — but do not expect to retint it from here
   without inlining the SVG first. */
.mark-badge { display: block; }

/* Category chips, the reference's coloured-dot tags. Scoped to .tag so the
   existing .ins.warning / .ins.suggestion variants keep their own colours. */
.tag.tag-cat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--brand-green-soft);
  border-color: var(--brand-green-line);
  color: var(--brand-green);
}
.tag.tag-cat::before {
  content: '';
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--brand-green);
  flex: none;
}

/* ==========================================================================
   Sign-in in the reference's green register — 2026-09-01
   The Caye login the user is matching uses a green mark and green field/link
   accents on a white card. The card and page furniture were already converted;
   this recolours the accents from navy to green, scoped to .auth-page so the
   rest of the app keeps navy as its primary.
   ========================================================================== */
/* Field focus goes green rather than navy */
body.auth-page .auth-card input[type="email"]:focus,
body.auth-page .auth-card input[type="password"]:focus,
body.auth-page .auth-card input[type="text"]:focus {
  border-color: var(--brand-green);
  box-shadow: inset 0 0 0 1px var(--brand-green);
  outline: none;
}
body.auth-page .auth-card .field:focus-within > label { color: var(--brand-green); }

/* Primary action: solid green, matching the mark */
body.auth-page .auth-card button[type="submit"] {
  background: var(--brand-green);
  color: #FFFFFF;
}
body.auth-page .auth-card button[type="submit"]:hover {
  background: var(--brand-green-hover);
  box-shadow: var(--shadow-hover);
}

/* In-card links (Forgot your password?, biometrics) go green.
   auth-links under the card stay white — they sit on the photograph. */
body.auth-page .auth-card a,
body.auth-page .auth-alt a { color: var(--brand-green); font-weight: 600; }
body.auth-page .auth-card .btn-ghost {
  border-color: var(--brand-green-line);
  color: var(--brand-green);
}
body.auth-page .auth-card .btn-ghost:hover {
  border-color: var(--brand-green);
  background: var(--brand-green-soft);
}
/* The remember-me checkbox tick */
body.auth-page .auth-card input[type="checkbox"] { accent-color: var(--brand-green); }
/* The password show/hide toggle */
body.auth-page .auth-card .pw-toggle:hover { color: var(--brand-green); }

/* ==========================================================================
   Sign-in benefits panel as a glassmorphic green-text box — 2026-09-02
   Requested: the "Open an account" link and the three benefits, in a frosted
   box with green text, sitting on the photograph beside the card.
   The glass is kept fairly opaque (white at 0.62) on purpose: green text over a
   bright beach photo through thin glass would not clear contrast, so the panel
   carries most of its own light and the blur adds the frosted quality.
   ========================================================================== */
body.auth-page .auth-links {
  align-self: center;
  width: 100%;
  max-width: 430px;
  padding: 20px 22px;
  border-radius: var(--radius-lg);
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.62);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  backdrop-filter: blur(16px) saturate(1.2);
  box-shadow: 0 8px 32px rgba(18, 35, 58, 0.18);
}
/* All text inside the glass goes green, overriding the white-on-photo default
   set for the links elsewhere. */
body.auth-page .auth-links a,
body.auth-page .auth-links .auth-points li {
  color: var(--brand-green);
}
body.auth-page .auth-links a { font-weight: 700; }
body.auth-page .auth-links a:hover { color: var(--brand-green-hover); }
body.auth-page .auth-links .auth-points li { font-weight: 600; }
/* The tick badge goes green to match */
body.auth-page .auth-links .auth-points li::before {
  background: var(--brand-green);
  color: #FFFFFF;
}

/* The brand block became an <a> (logo links home) — keep it looking like a
   logo, not a text link: no underline, inherit colour, and the sub-label
   stays put on hover. */
a.brand-logo-block, a.brand-logo-block:hover { text-decoration: none; color: inherit; }
a.brand-logo-block .brand-sub { text-decoration: none; }

/* Transfer form: fixed label column so every control lines up down the form. */
#detailsForm .field {
  display: grid;
  grid-template-columns: 160px minmax(0, 1fr);
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 12px;
  max-width: 560px;
}
#detailsForm .field > label { grid-column: 1; margin: 0; justify-self: start; }
#detailsForm .field > :not(label) { grid-column: 2; width: 100%; margin: 0; }
@media (max-width: 560px) {
  #detailsForm .field { grid-template-columns: 1fr; }
  #detailsForm .field > label, #detailsForm .field > :not(label) { grid-column: 1; }
}

/* Staff appear to customers as the bank: a "BI" badge and "Banco Insular". */
.chat-avatar.chat-bank {
  display: grid;
  place-items: center;
  background: var(--brand-navy-hero);
  color: var(--text-on-dark);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ==========================================================================
   Sign-in in blue — 2026-09-30
   Requested: every green on the sign-in pages goes blue. The green rules above
   all read var(--brand-green*), so redefining those four on body.auth-page
   recolours the sign-in and password-reset pages only; the client area keeps
   its green chips and badge. #1D4ED8 is 6.7:1 on white, so it holds as link
   text and as the fill behind the white button label.
   ========================================================================== */
body.auth-page {
  --brand-green: #1D4ED8;
  --brand-green-hover: #1E40AF;
  --brand-green-soft: #EFF6FF;
  --brand-green-line: #BFDBFE;
}

/* ==========================================================================
   GREEN AND GOLD — 2026-10-26
   Requested: the whole app redesigned in the style of a reference landing page
   (deep green, gold calls to action, bold geometric headlines, a photograph
   fading into the green, a white strip of short facts, rows of cards on the
   green). The reference belonged to a real bank, so only the visual language
   is taken — no name, copy, logo or photograph from it. The app carries no
   bank name at all, at the user's instruction; the logo is one file,
   /img/brand-logo.png, which the user uploads.

   Everything is in this block. Earlier palettes above stay as they were, so
   deleting this block (and the lp-* markup in index.html) returns the previous
   design.

   Contrast, measured: white on --g-700 6.9:1, on --g-800 9.1:1; --g-ink on
   --gold 7.2:1; --gold-soft on --g-700 5.0:1; --g-700 on white 6.9:1.
   ========================================================================== */
:root {
  --g-900: #0F3D27;
  --g-800: #145234;
  --g-700: #1A6440;
  --g-600: #22784D;
  --g-ink: #10301F;
  --g-tint: #EDF3EE;
  --gold: #D4A54A;
  --gold-hover: #C29236;
  --gold-soft: #EBCB86;

  --brand-blue-primary: var(--g-700);
  --brand-blue-hover: var(--g-800);
  --brand-navy-hero: var(--g-800);
  --brand-navy-dark: var(--g-900);

  --bg-app: #F3F5F2;
  --bg-card: #FFFFFF;
  --bg-muted: #EAEFEA;
  --text-primary: #13261C;
  --text-secondary: #4E5D54;
  --text-muted: #56655C;
  --border-soft: #E0E7E1;
  --border-strong: #C6D2C9;
  --silver: #9AAA9F;
  --silver-strong: #5F7266;

  --shadow-card: 0 1px 2px rgba(15, 61, 39, 0.06), 0 2px 8px rgba(15, 61, 39, 0.06);
  --shadow-hover: 0 2px 4px rgba(15, 61, 39, 0.08), 0 6px 16px rgba(15, 61, 39, 0.10);
  --shadow-float: 0 10px 30px rgba(15, 61, 39, 0.18);

  /* The reference is square-shouldered: small radii throughout. */
  --radius-sm: 4px;
  --radius-md: 6px;
  --radius-lg: 8px;

  --font-head: 'Montserrat', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Source Sans 3', 'Segoe UI', system-ui, sans-serif;
}

body { font-family: var(--font-body); font-size: 14.5px; }
h1, h2, h3, h4,
.dash-head h2, .sec-head h3, .page-hero-body h2 {
  font-family: var(--font-head);
  letter-spacing: -0.01em;
}
h1, h2 { font-weight: 800; }
h3 { font-weight: 700; }

/* ---- buttons: gold is the call to action, outline green is secondary ---- */
button[type="submit"], .btn-primary {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--g-ink);
  font-weight: 700;
}
button[type="submit"]:hover, .btn-primary:hover {
  background: var(--gold-hover);
  border-color: var(--gold-hover);
  color: var(--g-ink);
}
button, .btn { border-radius: var(--radius-sm); }
a { color: var(--g-700); }

/* ---- sidebar: the green rail ---- */
#sidebar {
  background: var(--g-800);
  border-right: 0;
  color: rgba(255, 255, 255, 0.86);
}
/* The logo is whatever file the user uploads, of unknown proportions, so it
   is bounded on both axes rather than given a width. */
.brand-logo {
  width: auto;
  max-width: 168px;
  max-height: 64px;
  margin: 0 0 6px;
}
#sidebar .brand-sub,
.brand-logo-block .brand-sub { color: var(--gold-soft); font-weight: 600; }
#sidebar nav a { color: rgba(255, 255, 255, 0.82); font-weight: 600; }
#sidebar nav a svg { opacity: 0.8; }
#sidebar nav a:hover { background: rgba(255, 255, 255, 0.08); color: #FFFFFF; }
#sidebar nav a.active {
  background: rgba(255, 255, 255, 0.12);
  color: #FFFFFF;
  box-shadow: inset 3px 0 0 var(--gold);
}
#sidebar .who { border-top-color: rgba(255, 255, 255, 0.16); color: rgba(255, 255, 255, 0.78); }
#sidebar .who-id .who-name { color: #FFFFFF; }
#sidebar .who-id .who-mail { color: rgba(255, 255, 255, 0.66); }
#sidebar .who > a { color: var(--gold-soft); font-weight: 600; }
#sidebar .avatar-disc { background: var(--gold); color: var(--g-ink); }
#sidebar .flag-picker-btn {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.28);
  color: #FFFFFF;
}
#sidebar .flag-picker-btn:hover { border-color: var(--gold-soft); }
#sidebar .flag-picker-caret { color: rgba(255, 255, 255, 0.7); }
.lp-lang .flag-picker-btn { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.45); color: #FFFFFF; }
.lp-lang .flag-picker-caret { color: #FFFFFF; }
@media (max-width: 900px) {
  /* On a phone the rail becomes a bar above #main, and every child of #main is
     its own stacking context (the fadeInUp animation), so the language list
     dropping out of the bar painted underneath the page. The rail also keeps
     overflow-y: auto from the desktop layout, which clipped the list at the
     bar's bottom edge; as a bar it has nothing to scroll, so it may overflow. */
  #sidebar { border-bottom: 0; position: relative; z-index: 50; overflow: visible; }
  #sidebar nav a { border-color: rgba(255, 255, 255, 0.2); }
  #sidebar nav a.active { border-color: var(--gold); box-shadow: none; }
}

/* ---- the hero band: green, photograph fading in from the right ---- */
.page-hero {
  border: 0;
  border-radius: var(--radius-md);
  background: var(--g-700);
  min-height: 150px;
}
.page-hero-scene { background-image: none; }
.page-hero-photo {
  left: 38%;
  background-position: 60% 45%;
}
.page-hero-scene::after {
  background:
    linear-gradient(90deg, var(--g-700) 0%, var(--g-700) 46%, rgba(26, 100, 64, 0.86) 58%, rgba(26, 100, 64, 0.34) 78%, rgba(26, 100, 64, 0.08) 100%);
}
.page-hero-body { padding: 30px 32px; max-width: 58%; }
.page-hero-eyebrow { color: var(--gold-soft); letter-spacing: 0.16em; }
.page-hero-body h2,
.page-hero-body .dash-head h2 {
  font-size: 30px;
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.02em;
}
.page-hero-body .muted,
.page-hero-body .dash-head p,
.page-hero-sub { color: rgba(255, 255, 255, 0.84); font-size: 14px; }
@media (max-width: 900px) {
  .page-hero-photo { left: 0; opacity: 0.45; }
  .page-hero-body { max-width: 100%; padding: 22px 20px; }
  .page-hero-body h2, .page-hero-body .dash-head h2 { font-size: 24px; }
}

/* ---- account tiles: the reference's rate cards ---- */
.acct-tile {
  background: var(--g-700);
  border-radius: var(--radius-md);
  min-width: 220px;
  padding: 18px 20px;
}
.acct-tile:hover { background: var(--g-600); }
.acct-tile[aria-current="true"] { background: var(--g-800); box-shadow: inset 0 -3px 0 var(--gold); }
.acct-tile-bal { font-family: var(--font-head); font-weight: 800; font-size: 24px; letter-spacing: -0.01em; }
.acct-tile-name { color: #FFFFFF; font-weight: 700; font-size: 13px; }
.acct-tile-cur { color: rgba(255, 255, 255, 0.8); }
.acct-tile-foot { color: rgba(255, 255, 255, 0.72); }

/* ---- quick actions ---- */
.qa-disc { border-color: var(--g-700); color: var(--g-700); }
.qa:hover .qa-disc { background: var(--g-700); border-color: var(--g-700); color: #FFFFFF; }

/* ---- surfaces and section heads ---- */
.sec-head::after { background: var(--gold); }
th { background: var(--g-tint); color: var(--g-ink); }
.site-foot { background: var(--g-900); border-radius: var(--radius-md); }

/* ---- support chat: the bank's replies carry the logo ---- */
.chat-avatar.chat-bank {
  background: #FFFFFF url("/img/brand-logo.png?v=202610261955") center / 78% no-repeat;
  border: 1px solid var(--border-soft);
  color: transparent;
}

/* ==========================================================================
   Sign-in (index.html, body.lp)
   ========================================================================== */
body.lp { background: var(--bg-app); }
.lp-wrap { width: 100%; max-width: 1180px; margin: 0 auto; padding: 0 32px; }

.lp-hero {
  position: relative;
  overflow: hidden;
  background: var(--g-700);
  color: #FFFFFF;
  padding-bottom: 56px;
}
.lp-photo {
  position: absolute;
  top: 0; bottom: 0; right: 0;
  width: 58%;
  background: url("/img/scene/coast-day.jpg?v=202610261955") 50% 40% / cover no-repeat;
}
/* The photograph fades itself out with a mask rather than having green
   painted over it, so there is no edge where the layer begins. */
.lp-photo {
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 22%, #000 62%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 22%, #000 62%);
}
.lp-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(26, 100, 64, 0.18);
}
[dir="rtl"] .lp-photo { right: auto; left: 0; transform: scaleX(-1); }

/* Above .lp-main: the language list drops out of this header and has to
   paint over the sign-in card. Both used to be z-index 2, so the card, coming
   later in the page, covered the list. */
.lp-top {
  position: relative;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-top: 22px;
  padding-bottom: 22px;
}
.lp-brand { display: inline-flex; align-items: center; }
.lp-logo { display: block; width: auto; max-width: 180px; max-height: 56px; }

.lp-main {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 400px;
  gap: 56px;
  align-items: center;
  padding-top: 26px;
}
.lp-eyebrow {
  margin: 0 0 14px;
  min-height: 1em;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-soft);
}
.lp-copy h1 {
  margin: 0 0 18px;
  font-family: var(--font-head);
  font-weight: 800;
  font-size: clamp(36px, 4.6vw, 58px);
  line-height: 1.06;
  letter-spacing: -0.025em;
  color: #FFFFFF;
  max-width: 13ch;
}
.lp-lead {
  margin: 0 0 28px;
  max-width: 46ch;
  font-size: 18px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
}
.lp-ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 22px; }
.lp-btn-gold {
  display: inline-flex;
  align-items: center;
  min-height: 50px;
  padding: 0 26px;
  border-radius: var(--radius-sm);
  background: var(--gold);
  color: var(--g-ink);
  font-weight: 700;
  font-size: 15.5px;
  text-decoration: none;
  transition: background 150ms ease;
}
.lp-btn-gold:hover { background: var(--gold-hover); color: var(--g-ink); text-decoration: none; }
.lp-fine { max-width: 46ch; font-size: 13px; line-height: 1.55; color: rgba(255, 255, 255, 0.82); }
.lp-fine .auth-link { display: none; }
.lp-secure { display: flex; gap: 10px; align-items: flex-start; }
.lp-secure svg { flex: none; margin-top: 2px; color: var(--gold-soft); }
.lp-secure b { display: block; color: #FFFFFF; margin-bottom: 2px; }

/* the card: white, square-shouldered, gold submit */
.lp .lp-card {
  width: 100%;
  max-width: none;
  margin: 0;
  padding: 30px 30px 26px;
  border: 0;
  border-radius: var(--radius-md);
  background: #FFFFFF;
  color: var(--text-primary);
  box-shadow: var(--shadow-float);
}
.lp .lp-card h2 { margin: 0 0 18px; font-size: 22px; color: var(--g-ink); }
.lp .lp-card .field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.lp .lp-card .field label { font-size: 13px; font-weight: 600; color: var(--text-secondary); }
.lp .lp-card input[type="email"],
.lp .lp-card input[type="password"],
.lp .lp-card input[type="text"] {
  width: 100%;
  min-height: 48px;
  padding: 0 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: #FFFFFF;
  font: inherit;
  font-size: 15px;
  color: var(--text-primary);
}
.lp .lp-card input:focus {
  outline: none;
  border-color: var(--g-700);
  box-shadow: 0 0 0 3px rgba(26, 100, 64, 0.16);
}
.lp .lp-card .pw-wrap { position: relative; display: block; }
.lp .lp-card .pw-wrap input { padding-inline-end: 46px; }
.lp .lp-card .pw-toggle {
  position: absolute;
  inset-inline-end: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 36px; height: 36px; min-height: 0;
  padding: 0;
  display: grid; place-items: center;
  border: 0; background: none; box-shadow: none;
  color: var(--text-muted);
}
.lp .lp-card .pw-toggle:hover { color: var(--g-700); background: none; }
.lp .lp-card .auth-remember { display: flex; align-items: center; gap: 8px; margin: 2px 0 18px; font-size: 14px; color: var(--text-secondary); }
.lp .lp-card .auth-remember input { accent-color: var(--g-700); width: 17px; height: 17px; }
.lp .lp-card button[type="submit"] {
  width: 100%;
  min-height: 50px;
  font-size: 15.5px;
}
.lp .lp-card .auth-msg { min-height: 18px; margin: 10px 0 0; font-size: 13px; color: var(--accent-red); }
.lp .lp-card .auth-alt { margin: 6px 0 0; text-align: center; }
.lp .lp-card .auth-alt a { color: var(--g-700); font-weight: 700; }
.lp .lp-card .divider { margin: 18px 0; }
.lp .lp-card .btn-ghost {
  width: 100%;
  min-height: 46px;
  border: 1px solid var(--g-700);
  border-radius: var(--radius-sm);
  background: #FFFFFF;
  color: var(--g-700);
  font-weight: 700;
}
.lp .lp-card .btn-ghost:hover { background: var(--g-tint); }

/* the white strip of short facts */
.lp-strip { background: #FFFFFF; border-bottom: 1px solid var(--border-soft); }
.lp-points {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 12px 40px;
  margin-top: 0; margin-bottom: 0;
  padding-top: 18px; padding-bottom: 18px;
}
.lp-points li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--g-ink);
}
.lp-points li::before {
  content: "";
  width: 18px; height: 18px;
  flex: none;
  background: var(--g-700);
  -webkit-mask: var(--pt-icon) center / contain no-repeat;
  mask: var(--pt-icon) center / contain no-repeat;
}
.lp-points .pt-cur  { --pt-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18'/%3E%3C/svg%3E"); }
.lp-points .pt-card { --pt-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2'/%3E%3Cpath d='M3 10h18M7 15h4'/%3E%3C/svg%3E"); }
.lp-points .pt-key  { --pt-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M12 3l7 3v5c0 5-3 8-7 10-4-2-7-5-7-10V6z'/%3E%3C/svg%3E"); }

/* the green band of cards */
.lp-band { background: var(--g-800); color: #FFFFFF; padding: 44px 0 52px; }
.lp-band h2 { margin: 0 0 22px; font-size: 26px; color: #FFFFFF; }
.lp-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.lp-tile {
  padding: 22px 22px 20px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.05);
}
.lp-num {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-head);
  font-weight: 800;
  font-size: 32px;
  line-height: 1;
  color: var(--gold-soft);
}
.lp-tile p { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.45; color: #FFFFFF; }

@media (max-width: 980px) {
  .lp-main { grid-template-columns: 1fr; gap: 32px; padding-top: 24px; }
  .lp-photo { width: 100%; opacity: 0.5; -webkit-mask-image: linear-gradient(180deg, #000 0%, transparent 75%); mask-image: linear-gradient(180deg, #000 0%, transparent 75%); }
  .lp-copy h1 { max-width: none; }
  .lp-cards { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .lp-wrap { padding: 0 16px; }
  .lp .lp-card { padding: 24px 18px 20px; }
  .lp-lead { font-size: 16px; }
  .lp-points { gap: 10px 24px; }
}

/* ---- registration (body.reg-page): the band goes green, photo on the right ---- */
.reg-band { background: var(--g-700); }
.reg-page .auth-scene {
  clip-path: none;
  left: 38%;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 25%, #000 65%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 25%, #000 65%);
}
.reg-page .auth-scene::after { background: rgba(26, 100, 64, 0.22); }
.reg-page .auth-rim { display: none; }
.reg-page .brand-sub { color: var(--gold-soft); }
.reg-hero .auth-greet { color: var(--gold-soft); letter-spacing: 0.16em; }
.reg-hero h1 { font-family: var(--font-head); font-weight: 800; }
.reg-top .flag-picker-btn { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.45); color: #FFFFFF; }
.reg-top a { color: #FFFFFF; }

/* ---- password reset (body.auth-page, the only page left on that class) ---- */
body.auth-page {
  --brand-green: var(--g-700);
  --brand-green-hover: var(--g-800);
  --brand-green-soft: var(--g-tint);
  --brand-green-line: #A9C7B3;
}
body.auth-page .auth-scene {
  background-image: none;
  background-color: var(--g-700);
}
body.auth-page .auth-scene .auth-photo {
  display: block;
  position: absolute;
  inset: 0 0 0 auto;
  width: 58%;
  height: auto;
  margin: 0;
  border: 0;
  border-radius: 0;
  clip-path: none;
  box-shadow: none;
  background: url("/img/scene/coast-day.jpg?v=202610261955") 50% 40% / cover no-repeat;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 22%, #000 62%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.35) 22%, #000 62%);
  opacity: 0.9;
}
body.auth-page .auth-card { border-radius: var(--radius-md); }
body.auth-page .auth-card button[type="submit"],
body.auth-page .auth-card button[type="submit"]:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--g-ink);
}
body.auth-page .auth-card button[type="submit"]:hover { background: var(--gold-hover); }
/* It only ever held the security note, which this layout hides — so it drew
   as an empty frosted box under the card. */
body.auth-page .auth-links { display: none; }
body.auth-page .auth-lang .flag-picker-btn { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.45); color: #FFFFFF; }
body.auth-page .brand-sub { color: var(--gold-soft); }
@media (max-width: 900px) {
  .reg-page .auth-scene { left: 0; opacity: 0.5; -webkit-mask-image: none; mask-image: none; }
  body.auth-page .auth-scene .auth-photo { width: 100%; opacity: 0.45; }
}

/* ---- open dropdowns always paint on top ----
   Every direct child of #main carries the fadeInUp animation, which makes each
   one its own stacking context, so a language or currency list opened inside
   one section was painted underneath the sections after it (seen on Loans and
   Investments). Whichever section holds an OPEN picker is lifted above its
   neighbours for as long as it is open. */
#main > *:has(.flag-picker-btn[aria-expanded="true"]),
#main > *:has(.acct-switch-btn[aria-expanded="true"]) {
  position: relative;
  z-index: 45;
}
