/* 718 Member Account — design system.
 *
 * A deliberate departure from /app (the DigitWallet member app), which is dark, dense, and
 * built out of nested iframes. The lessons applied here:
 *
 *   1. Light chrome, brand on the card. Amex and Barclaycard keep the interface calm and let
 *      the card carry the identity. Obsidian and gold stay on the card face; everything
 *      around it is warm off-white so balances and buttons read instantly.
 *   2. No iframes anywhere. The old shell embedded pages inside pages, which buried the card
 *      reveal and produced a 62,000px runaway frame. Pages here are just pages.
 *   3. State is always on screen. Money products fail when the member cannot tell what is
 *      happening, so every card, balance and action carries an explicit status.
 *   4. Plain language. No crypto or payments jargon on member-facing surfaces.
 *
 * Mobile web app first: single column, thumb-reachable actions, 44px minimum targets.
 */

:root {
  /* Surfaces: warm, not clinical. A pure white would fight the brand's ivory. */
  --bg:            #F7F4ED;
  --surface:       #FFFFFF;
  --surface-sunk:  #F2EEE4;
  --line:          #E4DED0;
  --line-strong:   #D3CABA;

  /* Ink. Near-black rather than black, which reads softer on a warm background. */
  --ink:           #1A1A1C;
  --ink-2:         #4A4640;
  --muted:         #7A7266;

  /* Brand gold, used sparingly: the card, focus rings, and one primary action per screen. */
  --gold:          #C9A667;
  --gold-deep:     #8C6F3C;
  --gold-tint:     #F5EEDD;

  /* Obsidian, reserved for the card face and the top bar mark. */
  --obsidian:      #0B0B0D;
  --obsidian-2:    #1C1B20;

  /* Status. Financial UI needs these to be unmistakable, not decorative. */
  --ok:            #1F7A4C;
  --ok-tint:       #E7F3EC;
  --warn:          #8A6100;
  --warn-tint:     #FBF1DC;
  --stop:          #A32B2B;
  --stop-tint:     #F9E9E9;

  --serif: 'Cormorant Garamond', Georgia, serif;
  --sans:  'Schibsted Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Motion. This system had none, so every duration here was a literal and every curve was a
     browser default. The names match assets/718.css (--dur-*, --ease-*) rather than inventing
     a third vocabulary: the marketing site and the member app are one product, and a member
     crossing from one to the other should not feel the timing change under them.
     ease-out on everything that enters or responds - it starts fast, which is the half of the
     curve the member is actually watching. */
  --ease:      cubic-bezier(.22,.61,.36,1);
  --ease-out:  cubic-bezier(.16,1,.3,1);
  --dur-fast:  150ms;
  --dur-base:  300ms;
  --dur-slow:  500ms;

  --radius:    14px;
  --radius-sm: 10px;
  --shadow:    0 1px 2px rgba(26,26,28,.04), 0 8px 24px rgba(26,26,28,.06);
  --shadow-lift: 0 2px 6px rgba(26,26,28,.06), 0 16px 40px rgba(26,26,28,.10);

  --wrap: 560px; /* one comfortable column; the app is mobile-first even on desktop */
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Room for the fixed action bar on small screens, plus the iOS home indicator. */
  padding-bottom: calc(96px + env(safe-area-inset-bottom));
}

/* Numbers are tabular everywhere. Money that shifts position as it changes looks unstable. */
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

.wrap { width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

/* ---------- top bar ---------- */
.topbar {
  position: sticky; top: 0; z-index: 20;
  background: rgba(247,244,237,.88);
  backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.topbar-in {
  display: flex; align-items: center; justify-content: space-between;
  height: 60px; max-width: var(--wrap); margin: 0 auto; padding: 0 20px;
}
.mark { font-weight: 600; font-size: 21px; letter-spacing: .04em; color: var(--ink); }
.mark span {
  font-family: var(--mono); font-size: 9px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--muted); margin-left: 7px; vertical-align: 3px;
}
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; height: 44px; border: 0; background: none; cursor: pointer;
  color: var(--ink-2); font-size: 14px; font-family: var(--sans); border-radius: var(--radius-sm);
}
@media(hover:hover) and (pointer:fine){
  .iconbtn:hover { background: var(--surface-sunk); }
}
.iconbtn:active { transform: scale(.94); }

/* ---------- section heading ---------- */
.eyebrow {
  font-family: var(--mono); font-size: 10px; letter-spacing: .2em;
  text-transform: uppercase; color: var(--muted);
}
h1 { font-family: var(--serif); font-size: 30px; font-weight: 500; letter-spacing: -.01em; line-height: 1.15; }
h2 { font-size: 15px; font-weight: 600; letter-spacing: .01em; }

/* ---------- notice: the state banner ---------- */
.notice {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 16px; border-radius: var(--radius); margin-bottom: 18px;
  border: 1px solid transparent; font-size: 14px; line-height: 1.45;
}
.notice-warn { background: var(--warn-tint); border-color: #EBD9AE; color: #6B4C00; }
.notice-ok   { background: var(--ok-tint);   border-color: #C7E3D3; color: #14512F; }
.notice-stop { background: var(--stop-tint); border-color: #EDC9C9; color: #7E2020; }
.notice b { font-weight: 600; }
.notice-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; margin-top: 7px; flex: none; }

/* ---------- the card face ---------- */
.card {
  position: relative; aspect-ratio: 1.586 / 1; width: 100%;
  border-radius: 16px; padding: 22px;
  background:
    radial-gradient(120% 140% at 82% 6%, #2A2830 0%, transparent 56%),
    linear-gradient(158deg, #17161B 0%, #0B0B0D 62%);
  color: #EFE9DC; box-shadow: var(--shadow-lift);
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
/* A single hairline of gold, not a gradient wash. Restraint reads as premium. */
.card::after {
  content: ""; position: absolute; inset: 0; border-radius: 16px;
  border: 1px solid rgba(201,166,103,.22); pointer-events: none;
}
.card-top { display: flex; align-items: flex-start; justify-content: space-between; }
.card-mark { font-weight: 600; font-size: 19px; letter-spacing: .05em; }
.card-mark span {
  display: block; font-family: var(--mono); font-size: 8px; letter-spacing: .24em;
  text-transform: uppercase; color: rgba(239,233,220,.5); margin-top: 3px;
}
.card-scheme { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: rgba(239,233,220,.62); }
.card-pan {
  font-family: var(--mono); font-size: clamp(15px, 4.4vw, 19px); letter-spacing: .14em;
  color: #F3EEE3; white-space: nowrap;
}
.card-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; }
.card-label {
  font-family: var(--mono); font-size: 8px; letter-spacing: .18em;
  text-transform: uppercase; color: rgba(239,233,220,.45); margin-bottom: 3px;
}
.card-val { font-size: 13px; letter-spacing: .04em; color: #E8E1D2; }
/* Frozen cards are visibly, unmistakably frozen. */
/* Freezing is a deliberate, rare state change, so it is allowed to be seen happening. */
.card { transition: filter var(--dur-base) var(--ease); }
.card.is-frozen { filter: grayscale(.85) brightness(.82); }

/* ---------- balance ---------- */
.balance { text-align: center; padding: 26px 0 20px; }
.balance-amt {
  font-family: var(--sans); font-weight: 600; letter-spacing: -.02em;
  font-size: clamp(38px, 11vw, 52px); line-height: 1;
}
.balance-amt .cur { font-size: .5em; font-weight: 500; color: var(--muted); vertical-align: .42em; margin-right: 3px; }
.balance-label { margin-top: 8px; font-size: 13px; color: var(--muted); }

/* ---------- actions ---------- */
.actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 4px 0 26px; }
.action {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 14px 6px; min-height: 76px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  font-family: var(--sans); font-size: 11.5px; color: var(--ink-2); cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease);
}
@media(hover:hover) and (pointer:fine){
  .action:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
}
/* scale rather than translateY: the marketing site presses with scale(.97) and this is the
   same product. A 1px nudge is also barely perceptible on a phone, which is where this app
   is actually used - the four actions here are the primary controls on the account screen. */
.action:active { transform: scale(.97); }
.action:disabled { opacity: .45; cursor: not-allowed; }
.action svg { width: 20px; height: 20px; stroke: var(--ink); stroke-width: 1.6; fill: none; }
.action.primary { background: var(--gold-tint); border-color: #E5D5AE; }
.action.primary svg { stroke: var(--gold-deep); }

/* ---------- panels ---------- */
.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 16px; overflow: hidden;
}
.panel-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 15px 18px; border-bottom: 1px solid var(--line);
}
.panel-bd { padding: 6px 18px 12px; }
.link { font-size: 13px; color: var(--gold-deep); text-decoration: none; font-weight: 500; }
.link:hover { text-decoration: underline; }

/* rows */
.row { display: flex; align-items: center; gap: 13px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.row:last-child { border-bottom: 0; }
.row-ic {
  width: 36px; height: 36px; flex: none; border-radius: 10px; background: var(--surface-sunk);
  display: grid; place-items: center; color: var(--ink-2);
}
.row-ic svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 1.7; fill: none; }
.row-main { flex: 1; min-width: 0; }
.row-t { font-size: 14.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-s { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.row-amt { font-size: 14.5px; font-weight: 600; white-space: nowrap; }
.row-amt.in { color: var(--ok); }

/* status pills */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  letter-spacing: .02em;
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill-ok   { background: var(--ok-tint);   color: var(--ok); }
.pill-warn { background: var(--warn-tint); color: var(--warn); }
.pill-stop { background: var(--stop-tint); color: var(--stop); }
.pill-idle { background: var(--surface-sunk); color: var(--muted); }

/* ---------- explainer: the house rule, made a component ---------- */
.explain {
  display: flex; gap: 10px; padding: 13px 15px; margin-top: 2px;
  background: var(--surface-sunk); border-radius: var(--radius-sm);
  font-size: 13px; line-height: 1.5; color: var(--ink-2);
}
.explain svg { width: 15px; height: 15px; flex: none; margin-top: 2px; stroke: var(--muted); stroke-width: 1.7; fill: none; }

/* ---------- bottom bar ---------- */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  background: rgba(255,255,255,.94); backdrop-filter: saturate(140%) blur(12px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabbar-in { display: flex; max-width: var(--wrap); margin: 0 auto; }
.tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 9px 0 10px; min-height: 56px; text-decoration: none;
  color: var(--muted); font-size: 10.5px; letter-spacing: .01em;
}
.tab svg { width: 21px; height: 21px; stroke: currentColor; stroke-width: 1.6; fill: none; }
/* Navigation is tapped dozens of times a day: press confirmation only, no other motion. */
.tab { transition: transform 100ms var(--ease-out); }
.tab:active { transform: scale(.94); }
.tab[aria-current="page"] { color: var(--ink); }
.tab[aria-current="page"] svg { stroke: var(--gold-deep); }

/* ---------- focus: visible, on brand, never removed ---------- */
:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 2px; border-radius: 4px; }

@media (min-width: 600px) {
  body { padding-bottom: 40px; }
  /* Cap the card on wide screens. Stretched to a full column it stops reading as a card
     and starts reading as a banner, which is the opposite of the intent. */
  .card { max-width: 400px; margin: 0 auto; }
  .tabbar { position: static; background: none; border-top: 0; backdrop-filter: none; margin-top: 8px; }
  .tabbar-in { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
}

/* ---------- sheet: the card details reveal ----------
 * Used for one thing only, and built for it: showing a clear PAN and CVV for as long as it
 * takes to type them somewhere, then taking them away again. Slides up on mobile, centres on
 * desktop. The countdown is part of the design, not decoration: the member should be able to
 * see that this is about to disappear.
 */
.sheet {
  position: fixed; inset: 0; z-index: 60;
  display: grid; align-items: end; justify-items: center;
  background: rgba(11,11,13,.42); backdrop-filter: blur(3px);
  padding: 0; opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.sheet.open { opacity: 1; pointer-events: auto; }
.sheet-in {
  width: 100%; max-width: var(--wrap);
  background: var(--surface); border-radius: 20px 20px 0 0;
  padding: 20px 20px calc(22px + env(safe-area-inset-bottom));
  box-shadow: 0 -8px 40px rgba(11,11,13,.18);
  /* Exit is faster than entry: closing is the member's intent and must not be made to wait. */
  transform: translateY(14px); transition: transform var(--dur-fast) var(--ease-out);
}
.sheet.open .sheet-in { transform: translateY(0); transition-duration: 220ms; }
.sheet-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.sheet-hd h2 { font-size: 17px; font-weight: 600; }
.sheet-x {
  width: 32px; height: 32px; border-radius: 50%; border: 0; background: var(--surface-sunk);
  display: grid; place-items: center; cursor: pointer; color: var(--ink-2);
}
.sheet-x svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; }
.sheet-note { font-size: 12.5px; color: var(--muted); margin-bottom: 14px; }

/* Small print. Same 12.5px muted step the rest of the app uses for secondary text, given its
   own name because disclosure copy is a recurring need here - who issues the card, what the
   fees are, what the terms say - and it should not have to borrow a class named for a sheet. */
.fine { font-size: 12.5px; line-height: 1.55; color: var(--muted); }

/* one revealed field */
.dt { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.dt:last-of-type { border-bottom: 0; }
.dt-main { flex: 1; min-width: 0; }
.dt-l { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.dt-v {
  font-size: 17px; font-weight: 500; margin-top: 3px;
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
  overflow-wrap: anywhere;
}
/* The billing address is the one .dt-v value that is prose rather than digits. Tabular figures
   and the tracking that makes a card number readable put a visible gap in front of every comma
   in an address, so it reads as "8 The Green , Ste R , Dover". Same size and weight, normal
   spacing. */
.dt-v.is-text { font-variant-numeric: normal; letter-spacing: normal; }
.copy {
  flex: none; border: 1px solid var(--line); background: var(--surface);
  border-radius: 9px; padding: 7px 11px; font: inherit; font-size: 12.5px; font-weight: 500;
  color: var(--ink); cursor: pointer; min-height: 34px;
}
@media(hover:hover) and (pointer:fine){
  .copy:hover { background: var(--surface-sunk); }
}
/* Press feedback on the copy button, which had none. Its only confirmation was the label
   changing to "Copied" once the clipboard write resolved - so on a slow tap the member had
   no signal the control had heard them at all. */
.copy { transition: background var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease),
                    color var(--dur-fast) var(--ease),
                    transform var(--dur-fast) var(--ease-out); }
.copy:active { transform: scale(.96); }
.copy.done { color: var(--ok); border-color: var(--ok); }

@media (min-width: 560px) {
  .sheet { align-items: center; padding: 20px; }
  .sheet-in { border-radius: var(--radius); }
}


/* ---------- reduced motion ----------------------------------------------------
 * This system had no reduced-motion handling at all, on the surface a member uses
 * repeatedly rather than once. Same rule as the marketing site: nothing translates,
 * scales or loops; colour, opacity and border feedback stay, because those are how a
 * control says it is live and the preference is not asking us to remove that.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-property: opacity, color, background-color, border-color, fill, stroke !important;
  }
  .action:active, .copy:active, .iconbtn:active, .tab:active { transform: none !important; }
}

/* ---------- the Bluebanc face ---------------------------------------------------------
 * Mirrors the card as Apple Wallet renders it (7 Sep 2026): navy, "corporate" top-left, the
 * Bluebanc wordmark top-right, a chip, the last four, and the Mastercard mark. The member
 * should recognise the card in their wallet from the card on this page, not wonder whether
 * the black 718 face and the navy Bluebanc one are two different things. */
.card-bluebanc {
  color: #EEF1FF;
  background:
    radial-gradient(90% 120% at 12% 8%, rgba(70,90,200,.28) 0%, transparent 55%),
    radial-gradient(60% 70% at 88% 92%, rgba(40,60,170,.35) 0%, transparent 60%),
    repeating-radial-gradient(circle at 14% 110%, rgba(255,255,255,.035) 0 1px, transparent 1px 11px),
    linear-gradient(160deg, #1B2B7A 0%, #0E1A5C 45%, #060F3E 100%);
  justify-content: flex-start;
}
.card-bluebanc::after { display: none; }
.card-tier { font-size: 14px; font-weight: 500; letter-spacing: .01em; color: rgba(238,241,255,.86); }
.card-issuer {
  display: flex; align-items: center; gap: 7px;
  font-weight: 700; font-size: 14px; letter-spacing: .22em; color: #F2F4FF;
}
.card-issuer-mark { width: 20px; height: 20px; color: #F2F4FF; }
.card-chip { width: 50px; height: 38px; margin: 7% 0 auto 4px; }
.card-bluebanc .card-foot { align-items: flex-end; }
.card-bluebanc .card-pan {
  font-family: var(--sans); font-weight: 500; font-size: clamp(16px, 4.6vw, 20px);
  letter-spacing: .12em; color: #F2F4FF;
}
.card-meta {
  display: flex; gap: 14px; margin-top: 4px;
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: rgba(238,241,255,.6);
}
.card-meta span:empty { display: none; }
/* The Mastercard mark: two overlapping discs. Drawn, not an image, so it needs no asset. */
.card-mc { position: relative; width: 58px; height: 36px; flex: 0 0 auto; }
.card-mc i { position: absolute; top: 0; width: 36px; height: 36px; border-radius: 50%; }
.card-mc i:first-child { left: 0; background: #EB001B; z-index: 2; }
.card-mc i:last-child { right: 0; background: #F79E1B; z-index: 1; }
/* The lens where the two discs meet, Mastercard's orange-red. */
.card-mc::after {
  content: ""; position: absolute; top: 0; left: 11px; width: 36px; height: 36px; border-radius: 50%;
  background: #FF5F00; z-index: 3;
  clip-path: circle(18px at 25px 18px);
  -webkit-mask: radial-gradient(circle 18px at 18px 18px, #000 99%, transparent 100%);
  mask: radial-gradient(circle 18px at 18px 18px, #000 99%, transparent 100%);
}
.card-issued { text-align: center; font-size: 12.5px; color: var(--muted); margin: 12px 0 0; line-height: 1.5; }
.card-issued b { font-weight: 600; color: var(--ink, inherit); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
