/* ===========================================================================
   Application chrome.

   Built from the tokens in styles.css, so a payment screen reads as the same
   site as the hero: the same sky, the same ink, the same Instrument Serif for
   anything that carries weight, the same liquid button, the same easing.

   The only values added here are the two functional status colours below. An
   error that is only grey is an error people miss. Status is never carried by
   colour alone either — every state also has a word and a distinct shape.
   =========================================================================== */

/* An author `display` beats the user agent's `[hidden]`, and both the per-field
   error and the form-level banner are rendered up front and hidden until there
   is something to say. Without this, every field on every form carries a bare
   red "!" under it and every form an empty red box. */
[hidden]{display:none !important}

:root{
  --danger:#9a2f28;
  --positive:#1f5d4c;

  --surface:rgba(255,255,255,.55);
  --surface-hi:rgba(255,255,255,.8);
  --radius:12px;
  --shell-max:1180px;
}

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

/* A column, with the content taking whatever is left over.

   This used to be a four-row grid, which was one row per child until the two
   standing banners were added above the bar. With six children in four rows
   the 1fr landed on the app bar instead of the content, and any screen short
   enough to leave space grew a hand's width of empty sky under the wordmark.
   A flex column has no count to keep in step with. */
.shell{
  position:relative;
  z-index:1;
  min-height:100vh;
  min-height:100dvh;
  display:flex;
  flex-direction:column;
}
.shell > .main{flex:1}

/* The same sky behind every screen, with the poster's colours ghosted in at
   the top so the app feels like the landing page rather than a white box. */
body[data-route="app"]{
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(255,255,255,.7), rgba(255,255,255,0) 60%),
    var(--sky);
  background-attachment:fixed;
}

/* The one sticky element. Its children just stack inside it.

   It carries the sky itself because the notices below are translucent by
   design, and translucent over a scrolling list is just unreadable. */
.topbar{position:sticky;top:0;z-index:50;background:var(--sky)}

.appbar{
  display:flex;
  align-items:center;
  gap:.75rem;
  padding:.9rem max(var(--pad-x),16px);
  background:rgba(219,230,238,.78);
  backdrop-filter:blur(18px) saturate(140%);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  border-bottom:1px solid var(--line-soft);
}
.appbar .logo{font-size:1.2rem}
.appbar-spacer{flex:1}

.main{
  width:100%;
  max-width:var(--shell-max);
  margin:0 auto;
  padding:1.75rem max(var(--pad-x),16px) 7.5rem;
}
@media (min-width:901px){ .main{padding-bottom:4rem} }

/* Bottom navigation: thumb-reachable on a phone, a row on a desktop. */
.tabbar{
  position:fixed;
  left:0;right:0;bottom:0;
  z-index:45;
  display:grid;
  /* However many tabs there are — a hard-coded count goes wrong the first
     time one is added. */
  grid-auto-flow:column;
  grid-auto-columns:1fr;
  background:rgba(219,230,238,.9);
  backdrop-filter:blur(18px) saturate(140%);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  border-top:1px solid var(--line-soft);
  padding-bottom:env(safe-area-inset-bottom);
}
.tabbar a{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:4px;
  min-height:56px;
  padding:8px 4px;
  font-size:11px;
  letter-spacing:-.01em;
  color:var(--muted);
  position:relative;
  transition:color .3s var(--ease);
}
.tabbar a:hover{color:var(--ink)}
.tabbar a[aria-current="page"]{color:var(--ink)}
.tabbar a[aria-current="page"] .tab-dot{transform:scaleX(1)}
.tab-dot{
  position:absolute;
  left:22%;right:22%;
  bottom:6px;
  height:1.5px;
  background:currentColor;
  border-radius:2px;
  transform:scaleX(0);
  transition:transform .5s var(--ease);
}
.tabbar svg{width:20px;height:20px}

@media (min-width:901px){
  .tabbar{
    position:static;
    grid-auto-columns:auto;
    justify-content:center;
    gap:.35rem;
    border-top:0;
    border-bottom:1px solid var(--line-soft);
  }
  .tabbar a{flex-direction:row;min-height:44px;padding:0 1rem;font-size:.92rem;gap:.5rem}
  .tab-dot{left:1rem;right:1rem;bottom:8px}
}

/* ----------------------------------------------------------- typography -- */

.page-title{
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(2rem,3.6vw,2.9rem);
  line-height:1.1;
  letter-spacing:-.012em;
  margin:0 0 .35rem;
}
.page-title em{font-style:italic;color:var(--muted)}

.page-sub{
  margin:0;
  color:var(--muted);
  font-size:1rem;
  line-height:1.55;
  max-width:60ch;
}

.section{margin-top:2.25rem}
.section-head{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:.75rem;
  margin-bottom:.8rem;
}
.section-title{
  margin:0;
  font-size:.78rem;
  font-weight:500;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--quiet);
}
.section-link{font-size:.88rem;color:var(--muted);position:relative}
.section-link:hover{color:var(--ink)}

/* -------------------------------------------------------------- surfaces -- */

.card{
  border:1px solid var(--line-soft);
  border-radius:var(--radius);
  background:var(--surface);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  padding:1.15rem;
}
.card + .card{margin-top:.75rem}
.card-tight{padding:.9rem}

a.card{transition:transform .45s var(--ease), box-shadow .45s var(--ease), background-color .45s var(--ease)}
a.card:hover{
  transform:translateY(-2px);
  background:var(--surface-hi);
  box-shadow:0 14px 30px -20px rgba(0,0,0,.45);
}

.grid{display:grid;gap:.75rem}
@media (min-width:720px){ .grid-2{grid-template-columns:1fr 1fr} }
@media (min-width:900px){ .grid-3{grid-template-columns:repeat(3,1fr)} }

.row{display:flex;align-items:center;gap:.75rem}
.row-between{display:flex;align-items:center;justify-content:space-between;gap:.75rem}
.stack{display:flex;flex-direction:column;gap:.25rem;min-width:0}
.spread{flex:1;min-width:0}
.muted{color:var(--muted)}
.nowrap{white-space:nowrap}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ----------------------------------------------------------------- lists -- */

.list{
  border:1px solid var(--line-soft);
  border-radius:var(--radius);
  overflow:hidden;
  background:var(--surface);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
}
.list-item{
  display:flex;
  align-items:center;
  gap:.75rem;
  width:100%;
  min-height:60px;
  padding:.75rem .9rem;
  text-align:left;
  background:transparent;
  border:0;
  border-bottom:1px solid var(--line-soft);
  color:inherit;
  cursor:pointer;
  transition:background-color .3s var(--ease);
}
.list-item:last-child{border-bottom:0}
.list-item:hover{background:rgba(255,255,255,.6)}
.list-item[aria-disabled="true"]{cursor:default}
.list-item[aria-disabled="true"]:hover{background:transparent}
.list-title{font-size:.98rem;letter-spacing:-.005em}
.list-sub{font-size:.82rem;color:var(--muted)}
.list-amount{font-size:1rem;letter-spacing:-.01em;text-align:right;font-variant-numeric:tabular-nums}

/* ---------------------------------------------------------------- avatar -- */

.avatar{
  flex:none;
  display:grid;
  place-items:center;
  width:38px;height:38px;
  border-radius:50%;
  border:1px solid var(--line);
  background:rgba(255,255,255,.65);
  font-size:.82rem;
  font-weight:500;
  letter-spacing:-.01em;
  color:var(--ink);
  overflow:hidden;
}
.avatar img{width:100%;height:100%;object-fit:cover}
.avatar svg{width:18px;height:18px}
.avatar-lg{width:64px;height:64px;font-size:1.3rem}
.avatar-sm{width:28px;height:28px;font-size:.68rem}

/* ---------------------------------------------------------------- status -- */

.status{
  display:inline-flex;
  align-items:center;
  gap:6px;
  padding:4px 9px;
  border-radius:999px;
  border:1px solid var(--line);
  font-size:.72rem;
  letter-spacing:.01em;
  white-space:nowrap;
  color:var(--muted);
  background:rgba(255,255,255,.45);
}
.status::before{
  content:"";
  width:6px;height:6px;
  border-radius:50%;
  background:currentColor;
  flex:none;
}
.status-completed{color:var(--positive);border-color:rgba(31,93,76,.3)}
.status-pending::before{border-radius:1px;transform:rotate(45deg)}
.status-failed{color:var(--danger);border-color:rgba(154,47,40,.32)}
.status-failed::before{clip-path:polygon(50% 0,100% 100%,0 100%);border-radius:0}
.status-cancelled::before{background:none;box-shadow:inset 0 0 0 1px currentColor}

/* ----------------------------------------------------------------- forms -- */

.field{display:flex;flex-direction:column;gap:.35rem;margin-bottom:1rem}
.field label{font-size:.85rem;letter-spacing:-.005em;color:var(--ink)}
.field-hint{font-size:.78rem;color:var(--muted);line-height:1.5}

.input,.textarea,.select{
  width:100%;
  min-height:46px;
  padding:.72rem .85rem;
  border-radius:8px;
  border:1px solid var(--line);
  background:rgba(255,255,255,.7);
  color:var(--ink);
  font-family:inherit;
  font-size:1rem;
  letter-spacing:-.005em;
  transition:border-color .3s var(--ease), background-color .3s var(--ease), box-shadow .3s var(--ease);
}
.input::placeholder,.textarea::placeholder{color:var(--quiet)}
.input:hover,.textarea:hover,.select:hover{border-color:rgba(11,11,12,.3)}
.input:focus,.textarea:focus,.select:focus{
  outline:none;
  border-color:var(--ink);
  background:#fff;
  box-shadow:0 0 0 3px rgba(11,11,12,.07);
}
.textarea{min-height:86px;resize:vertical}
.select{appearance:none;padding-right:2.2rem}

.input[aria-invalid="true"],.textarea[aria-invalid="true"]{border-color:var(--danger)}
.field-error{font-size:.8rem;color:var(--danger);display:flex;gap:.4rem;align-items:flex-start}
.field-error::before{content:"!";font-weight:600}

.amount-input{
  font-family:var(--display);
  font-size:2.6rem;
  letter-spacing:-.01em;
  min-height:72px;
  text-align:center;
  font-variant-numeric:tabular-nums;
}

.inline-actions{display:flex;flex-wrap:wrap;gap:.5rem}

.btn-danger{
  background:transparent;
  color:var(--danger);
  border:1px solid rgba(154,47,40,.35);
}
.btn-danger:hover{background:rgba(154,47,40,.07);border-color:var(--danger);box-shadow:none}

/* Segmented control */
.segmented{
  display:inline-flex;
  padding:3px;gap:3px;
  border:1px solid var(--line-soft);
  border-radius:9px;
  background:rgba(255,255,255,.5);
}
.segmented button{
  min-height:34px;
  padding:0 .9rem;
  border-radius:6px;
  color:var(--muted);
  font-size:.88rem;
  transition:background-color .3s var(--ease), color .3s var(--ease);
}
.segmented button[aria-pressed="true"]{background:var(--ink);color:#fff}

/* Chips */
.chips{display:flex;flex-wrap:wrap;gap:.5rem}
.chip{
  display:inline-flex;align-items:center;gap:.4rem;
  min-height:36px;padding:0 .8rem;
  border:1px solid var(--line);border-radius:999px;
  background:rgba(255,255,255,.45);color:var(--muted);
  font-size:.85rem;
  transition:background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.chip[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink)}

/* -------------------------------------------------------------- progress -- */

.progress{
  height:6px;
  border-radius:999px;
  background:rgba(11,11,12,.1);
  overflow:hidden;
}
.progress-bar{
  height:100%;
  border-radius:999px;
  background:var(--ink);
  transition:width .9s var(--ease);
}

/* -------------------------------------------------- banners, toasts, modals -- */

.banner{
  display:flex;
  gap:.6rem;
  align-items:flex-start;
  padding:.8rem .9rem;
  border:1px solid var(--line);
  border-radius:9px;
  background:rgba(255,255,255,.55);
  font-size:.9rem;
  line-height:1.55;
  color:var(--ink);
}
.banner-danger{border-color:rgba(154,47,40,.35);background:rgba(154,47,40,.05);color:var(--danger)}
.banner-warn{border-color:var(--line);background:rgba(255,255,255,.7)}
.banner strong{font-weight:500}


.dev-banner{
  padding:.5rem 1rem;
  text-align:center;
  font-size:.8rem;
  letter-spacing:-.005em;
  background:repeating-linear-gradient(45deg, rgba(11,11,12,.07) 0 10px, rgba(11,11,12,.12) 10px 20px);
  border-bottom:1px solid var(--line);
  color:var(--ink);
}
.dev-banner a{text-decoration:underline}

/* The "no backend" note is information, not a warning: flat, not striped. */
.dev-banner--quiet{
  background:rgba(255,255,255,.55);
  border-bottom:1px solid var(--line-soft);
  color:var(--muted);
}

.unread-dot{
  position:absolute;
  transform:translate(10px,-10px);
  width:7px;height:7px;
  border-radius:50%;
  background:var(--ink);
}

.toast-host{
  position:fixed;
  left:50%;
  bottom:calc(5rem + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  z-index:120;
  display:flex;
  flex-direction:column;
  gap:.5rem;
  width:min(440px,calc(100vw - 2rem));
  pointer-events:none;
}
.toast{
  pointer-events:auto;
  padding:.8rem .9rem;
  border-radius:9px;
  border:1px solid var(--line);
  background:rgba(255,255,255,.92);
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
  box-shadow:0 18px 40px -24px rgba(0,0,0,.5);
  font-size:.9rem;
  line-height:1.45;
  animation:lift .5s var(--ease) both;
}
.toast-danger{border-color:rgba(154,47,40,.4)}
.toast-title{font-weight:500}
.toast-body{color:var(--muted);margin-top:2px}

dialog.modal{
  width:min(520px,calc(100vw - 2rem));
  max-height:86vh;
  padding:0;
  border:1px solid var(--line);
  border-radius:16px;
  background:var(--paper);
  color:var(--ink);
  overflow:auto;
  box-shadow:0 40px 80px -40px rgba(0,0,0,.5);
}
dialog.modal::backdrop{background:rgba(11,11,12,.32);backdrop-filter:blur(10px)}
.modal-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:1.15rem 1.15rem 0}
.modal-title{font-family:var(--display);font-weight:400;font-size:1.5rem;letter-spacing:-.01em;margin:0}
.modal-body{padding:1rem 1.15rem}
.modal-foot{display:flex;gap:.5rem;justify-content:flex-end;padding:0 1.15rem 1.15rem;flex-wrap:wrap}

.icon-btn{
  display:grid;place-items:center;
  width:40px;height:40px;
  border-radius:9px;
  border:1px solid transparent;
  color:var(--muted);
  transition:background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.icon-btn:hover{background:rgba(255,255,255,.6);color:var(--ink);border-color:var(--line-soft)}

/* --------------------------------------------------- empty / loading / error -- */

.empty{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.6rem;
  padding:2.5rem 1.25rem;
  text-align:center;
  border:1px dashed var(--line);
  border-radius:var(--radius);
  color:var(--muted);
}
.empty-title{
  font-family:var(--display);
  font-size:1.4rem;
  color:var(--ink);
  letter-spacing:-.01em;
}
.empty p{max-width:46ch;font-size:.9rem;line-height:1.6;margin:0}

.skeleton{
  border-radius:9px;
  background:linear-gradient(90deg, rgba(11,11,12,.05) 25%, rgba(11,11,12,.09) 37%, rgba(11,11,12,.05) 63%);
  background-size:400% 100%;
  animation:shimmer 1.4s ease infinite;
}
@keyframes shimmer{ from{background-position:100% 0} to{background-position:0 0} }
.skeleton-line{height:14px;margin-bottom:8px}
.skeleton-row{height:60px;margin-bottom:8px}

.spinner{
  width:16px;height:16px;flex:none;
  border-radius:50%;
  border:2px solid rgba(11,11,12,.22);
  border-top-color:var(--ink);
  animation:spin .7s linear infinite;
}
.btn .spinner{border-color:rgba(255,255,255,.35);border-top-color:#fff}
@keyframes spin{ to{transform:rotate(360deg)} }

/* ------------------------------------------------------- receipt / detail -- */

.detail-row{
  display:flex;
  justify-content:space-between;
  gap:1rem;
  padding:.7rem 0;
  border-bottom:1px solid var(--line-soft);
  font-size:.92rem;
}
.detail-row:last-child{border-bottom:0}
.detail-key{color:var(--muted)}
.detail-val{text-align:right;word-break:break-word}

.mono{
  font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:.8rem;
  letter-spacing:0;
}

details.advanced summary{
  cursor:pointer;
  padding:.6rem 0;
  font-size:.88rem;
  color:var(--muted);
  list-style:none;
}
details.advanced summary::-webkit-details-marker{display:none}
details.advanced summary::before{content:"\25B8  ";display:inline-block;transition:transform .3s var(--ease)}
details.advanced[open] summary::before{transform:rotate(90deg)}

.amount-hero{
  font-family:var(--display);
  font-size:clamp(2.4rem,5vw,3.4rem);
  line-height:1.05;
  letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;
}

/* -------------------------------------------------------------------- QR -- */

.qr{
  display:block;
  width:min(230px,62vw);
  height:auto;
  margin:0 auto;
  padding:12px;
  border-radius:12px;
  background:#fff;
  border:1px solid var(--line-soft);
}

/* ---------------------------------------------------------------- cursor -- */

.cursor-dot,.cursor-label{display:none}

/* Everything below hangs off `has-custom-cursor`, which cursor.js adds only
   while it is actually driving the thing.

   These used to be shown by the media query alone, which is not the same
   condition: the script also requires a viewport of at least 901px, so on
   any narrower window with a fine pointer the arrow was painted and nothing
   ever moved it — a second, frozen cursor parked at the top-left corner. The
   same happened whenever the script had not started, or had been torn down.
   Tying the graphic to the class means it cannot outlive the code that
   animates it. */
@media (pointer:fine) and (prefers-reduced-motion:no-preference){
  body.has-custom-cursor{cursor:none}
  body.has-custom-cursor a,body.has-custom-cursor button,body.has-custom-cursor input,
  body.has-custom-cursor textarea,body.has-custom-cursor select,body.has-custom-cursor [role="button"]{cursor:none}

  /* A full-screen, click-through popover: the dot's top-layer home. Popover
     defaults (centred, bordered, padded, painted) all undone. */
  .cursor-layer{
    position:fixed;
    inset:0;
    width:auto;height:auto;
    margin:0;padding:0;border:0;
    background:transparent;
    overflow:visible;
    pointer-events:none;
    z-index:2147483647;
  }
  .cursor-layer:popover-open{display:block}

  body.has-custom-cursor .cursor-dot{
    display:block;
    position:fixed;
    top:0;left:0;
    z-index:2147483647;
    width:22px;height:22px;
    pointer-events:none;
    will-change:transform;
    color:var(--ink);
    filter:drop-shadow(0 2px 6px rgba(255,255,255,.7));
  }
  body.has-custom-cursor .cursor-label{
    display:block;
    position:fixed;
    top:0;left:0;
    z-index:2147483647;
    padding:4px 8px;
    border-radius:6px;
    background:var(--ink);
    color:#fff;
    font-size:.75rem;
    letter-spacing:-.005em;
    white-space:nowrap;
    pointer-events:none;
    opacity:0;
    transition:opacity .2s ease;
    will-change:transform;
  }
  body.has-custom-cursor .cursor-label[data-visible="true"]{opacity:1}

  /* On the dark surfaces — the open menu, the sign-in scene — an ink-green
     arrow is invisible. Cream there, with a dark halo instead of a light one. */
  body.has-custom-cursor.k-menu-open .cursor-dot,
  body.has-custom-cursor[data-route="auth"] .cursor-dot{
    color:#E8E3D0;
    filter:drop-shadow(0 2px 6px rgba(0,0,0,.55));
  }
}

/* Page titles are focused when a page opens, so screen readers start there.
   They are not controls, and a focus ring round a heading is just a box
   round the text. Real buttons and fields keep theirs. */
h1[tabindex="-1"]:focus, h2[tabindex="-1"]:focus,
h1[tabindex="-1"]:focus-visible, h2[tabindex="-1"]:focus-visible,
[tabindex="-1"]:not(a):not(button):not(input):not(select):not(textarea):focus-visible{
  outline:none;
}

/* ------------------------------------------------------------ public pages -- */

.public-wrap{
  position:relative;
  z-index:1;
  min-height:100vh;
  min-height:100dvh;
  display:grid;
  grid-template-rows:auto 1fr;
}
.public-main{
  display:flex;
  align-items:center;
  justify-content:center;
  padding:1.5rem 1.25rem 4rem;
}
.public-card{
  width:min(460px,100%);
  border:1px solid var(--line-soft);
  border-radius:16px;
  background:rgba(255,255,255,.72);
  backdrop-filter:blur(18px) saturate(140%);
  -webkit-backdrop-filter:blur(18px) saturate(140%);
  box-shadow:0 30px 70px -45px rgba(0,0,0,.5);
  padding:1.6rem;
}

/* -------------------------------------------------------- standalone -- */
/* Installed, there is no browser chrome above the app bar and no browser
   gesture area below the tabs, so the window's own insets have to be
   respected or the wordmark sits under the clock. */

@media (display-mode:standalone),(display-mode:minimal-ui){
  html{overscroll-behavior-y:none}
  /* Both of these are sticky at the top of the scrollport, so both have to
     clear the status bar on their own — whichever one is under it. */
  .topbar{padding-top:env(safe-area-inset-top);background:var(--sky)}
  .main,.appbar,.tabbar{
    padding-left:max(var(--pad-x),env(safe-area-inset-left),16px);
    padding-right:max(var(--pad-x),env(safe-area-inset-right),16px);
  }
}

/* ------------------------------------------------------------- policy -- */

.policy-btn{
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  flex:none;
  padding:.45rem .7rem;
  border:1px solid var(--line-soft);
  border-radius:8px;
  background:var(--surface);
  color:var(--muted);
  font-size:.8rem;
  letter-spacing:-.005em;
  cursor:pointer;
  transition:color .3s var(--ease),border-color .3s var(--ease),background-color .3s var(--ease);
}
.policy-btn:hover{color:var(--ink);border-color:var(--line);background:var(--surface-hi)}
.policy-btn svg{width:15px;height:15px}

.policy section + section{margin-top:1.1rem}
.policy h3{
  margin:0 0 .3rem;
  font-size:.95rem;
  font-weight:500;
  letter-spacing:-.008em;
}
.policy p{margin:0;font-size:.88rem;line-height:1.65;color:var(--muted)}

/* ------------------------------------------------------------ receive -- */

.receive-card{text-align:center}
.receive-qr{
  display:flex;
  justify-content:center;
  padding:.9rem;
  margin:0 auto .9rem;
  width:fit-content;
  border-radius:10px;
  background:#fff;
  border:1px solid var(--line-soft);
}
.receive-qr svg{width:168px;height:168px;display:block}

.receive-network{
  margin:0 0 .7rem;
  font-size:.82rem;
  line-height:1.55;
  color:var(--muted);
}
.receive-network strong{font-weight:500;color:var(--ink)}

.receive-address{
  margin-bottom:.8rem;
  padding:.6rem .7rem;
  border-radius:8px;
  background:rgba(11,11,12,.04);
  border:1px solid var(--line-soft);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.76rem;
  line-height:1.5;
  word-break:break-all;
}

@media print{
  .appbar,.tabbar,.hero__media,.toast-host,.no-print{display:none !important}
  body,html{background:#fff !important;color:#000 !important}
  .card,.list{border-color:#ccc;background:none;backdrop-filter:none}
  .detail-key,.muted{color:#555 !important}
}

/* ========================================================== auth stage == */
/* Sign in, sign up and the username step.

   The record is the whole page: the landing hero's meadow, darkened, with a
   turntable drawn over it in CSS, and the form floating on top as a pane of
   glass. Drawn rather than streamed — the hero's footage is a multi-megabyte
   download and a sign-in screen has no business waiting on one — but it is
   the same photograph, the same serif and the same deck, so arriving here
   from the landing page does not feel like arriving somewhere else. */

body[data-route="auth"]{background:#0a0b0e}
body[data-route="auth"] .main{max-width:none;padding:0;display:flex}
/* Whatever the view hands back fills the window too. Sign-up and the setup
   steps wrap their stage in a plain container (they redraw into it), and as a
   flex item that container shrink-wrapped to its content — the form slid to
   the left edge and the record lost half the screen. */
body[data-route="auth"] .main > *{flex:1;display:flex;min-width:0}

.auth-stage{position:relative;flex:1;display:flex}

/* ----------------------------------------------------- inverted chrome -- */
/* The bar carries the sky on every other screen, and a pale strip across the
   top of a night scene is the one thing that would give away that this used
   to be a light page with a picture stuck to one side of it. */

body[data-route="auth"] .topbar{background:transparent}
body[data-route="auth"] .appbar{
  background:rgba(10,11,14,.3);
  border-bottom-color:rgba(255,255,255,.1);
}
body[data-route="auth"] .appbar .logo{color:#f4f1ea}
body[data-route="auth"] .icon-btn{color:rgba(244,241,234,.72)}
body[data-route="auth"] .icon-btn:hover{
  background:rgba(255,255,255,.12);
  color:#fff;
  border-color:rgba(255,255,255,.16);
}
body[data-route="auth"] .appbar .btn{background:#f4f1ea;color:#0b0b0c}
body[data-route="auth"] .appbar .btn:hover{background:#fff}
body[data-route="auth"] .appbar .btn-quiet{
  background:rgba(255,255,255,.1);
  color:#f4f1ea;
  border-color:rgba(255,255,255,.22);
}
body[data-route="auth"] .appbar .btn-quiet:hover{background:rgba(255,255,255,.2)}

body[data-route="auth"] .tabbar{
  background:rgba(10,11,14,.72);
  border-top-color:rgba(255,255,255,.1);
  border-bottom-color:rgba(255,255,255,.1);
}
body[data-route="auth"] .tabbar a{color:rgba(244,241,234,.6)}
body[data-route="auth"] .tabbar a:hover,
body[data-route="auth"] .tabbar a[aria-current="page"]{color:#f4f1ea}

/* ------------------------------------------------------------ the scene -- */
/* Fixed, so it is the window rather than the document: the page can be as
   long as the form makes it without the record sliding away up the screen. */

.auth-scene{
  position:fixed;
  inset:0;
  z-index:0;
  overflow:hidden;
  background:linear-gradient(200deg,#1b2530 0%,#101820 45%,#0a0b0e 100%);
}

.auth-scene::before{ /* the meadow */
  content:"";
  position:absolute;
  inset:0;
  background-image:var(--poster);
  background-size:cover;
  background-position:52% 58%;
  opacity:.44;
  filter:saturate(76%) contrast(104%);
}

/* The scrim. Weighted to whichever side the form is on, so the text always
   has night behind it and the record always keeps some daylight. */
.auth-scene::after{
  content:"";
  position:absolute;
  inset:0;
  background:linear-gradient(180deg,rgba(8,9,12,.5),rgba(8,9,12,.82));
}
@media (min-width:901px){
  .auth-scene::after{
    background:
      linear-gradient(90deg,rgba(8,9,12,.9) 0%,rgba(8,9,12,.66) 32%,rgba(8,9,12,.14) 62%,rgba(8,9,12,.3) 100%),
      linear-gradient(180deg,rgba(8,9,12,.12),rgba(8,9,12,.46));
  }
}

/* ------------------------------------------------------------- the deck -- */

.auth-deck{
  position:absolute;
  top:50%;
  right:clamp(.75rem,2.5vw,3.5rem);
  width:min(40rem,68vmin);
  aspect-ratio:1;
  transform:translateY(-46%);
}
/* Narrow: there is no room beside the form, so the record goes behind it —
   nearly the full width, high enough that the headline and the arm share the
   space above the card and the vinyl is the surface the type sits on. It
   stays inside the window horizontally, or the arm's bearing is cropped away
   and all that is left is a stick poking out of nothing. */
@media (max-width:900px){
  .auth-deck{
    top:3.25rem;
    right:2vw;
    width:min(25rem,88vw);
    transform:none;
  }
}

.auth-disc{
  position:absolute;
  inset:0;
  border-radius:50%;
  /* Grooves, then the light travelling round the vinyl as it turns. */
  background:
    repeating-radial-gradient(circle at 50% 50%,
      rgba(255,255,255,.06) 0 1px, rgba(0,0,0,0) 1px 5px),
    conic-gradient(from 210deg,
      #0a0a0c 0deg,#2a2a31 40deg,#0d0d10 90deg,#33333c 150deg,
      #0a0a0c 200deg,#26262d 265deg,#0c0c0f 315deg,#0a0a0c 360deg);
  box-shadow:
    0 0 0 1px rgba(255,255,255,.1),
    0 40px 70px -30px rgba(0,0,0,.85);
  animation:auth-spin 9s linear infinite;
}

.auth-disc__label{
  position:absolute;
  inset:35%;
  border-radius:50%;
  background:radial-gradient(circle at 42% 34%,#f0e6cf,#d8c6a0 62%,#c0a978);
  box-shadow:0 0 0 1px rgba(0,0,0,.35);
  color:#2a2113;
  font-family:var(--display);
  font-size:clamp(1rem,2.4vmin,1.5rem);
  letter-spacing:-.01em;
}
/* The name sits under the spindle, where a label prints it. */
.auth-disc__label > span{position:absolute;left:0;right:0;bottom:17%;text-align:center}
.auth-disc__label::after{ /* the spindle hole */
  content:"";
  position:absolute;
  left:50%;
  top:50%;
  width:8%;
  aspect-ratio:1;
  border-radius:50%;
  transform:translate(-50%,-50%);
  background:#0a0a0c;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
}

/* A highlight lying across the disc. It must not rotate with the record. */
.auth-disc__sheen{
  position:absolute;
  inset:0;
  border-radius:50%;
  background:linear-gradient(118deg,
    rgba(255,255,255,0) 30%,
    rgba(255,255,255,.16) 45%,
    rgba(255,255,255,.03) 52%,
    rgba(255,255,255,0) 66%);
  mix-blend-mode:screen;
  animation:auth-sheen 7s var(--ease-in-out) infinite;
}

/* ------- the tonearm ------- */
/* Bolted at the corner of the deck, which is the one part of the square that
   is outside the platter, and angled down into the groove — short enough to
   land between the label and the rim rather than across the print. */

.auth-arm{
  position:absolute;
  top:11%;
  right:5.5%;
  width:31%;
  height:.9%;
  min-height:4px;
  border-radius:99px;
  transform-origin:100% 50%;
  transform:rotate(-36deg);
  /* The fittings below are sized in em off this, so the whole arm scales with
     the deck rather than with the reader's body text. */
  font-size:clamp(7px,1.45vmin,15px);
  background:linear-gradient(180deg,#efece5,#b4afa6 55%,#6d6961);
  box-shadow:0 10px 22px -10px rgba(0,0,0,.9);
}
.auth-arm__pivot{ /* the bearing the arm swings on */
  position:absolute;
  right:-6%;
  top:50%;
  width:2.6em;
  height:2.6em;
  border-radius:50%;
  transform:translateY(-50%);
  background:radial-gradient(circle at 36% 30%,#f6f3ec,#9a958c 66%,#4e4a45);
  box-shadow:0 8px 18px -8px rgba(0,0,0,.9);
}
.auth-arm__weight{ /* counterweight, behind the bearing */
  position:absolute;
  right:-20%;
  top:50%;
  width:1.9em;
  height:1.5em;
  border-radius:3px;
  transform:translateY(-50%);
  background:linear-gradient(180deg,#3a3732,#1a1815);
  box-shadow:0 0 0 1px rgba(255,255,255,.12);
}
.auth-arm__head{ /* the headshell, down on the record */
  position:absolute;
  left:-2px;
  top:50%;
  width:1.9em;
  height:1.3em;
  border-radius:2px 1px 3px 3px;
  transform:translateY(-38%) rotate(8deg);
  background:linear-gradient(180deg,#e2ded5,#7a756e);
  box-shadow:0 6px 14px -6px rgba(0,0,0,.9);
}

@keyframes auth-spin{ to{ transform:rotate(360deg) } }
@keyframes auth-sheen{
  0%,100%{ opacity:.55; transform:translateX(-4%) }
  50%    { opacity:1;   transform:translateX(4%) }
}

/* ------------------------------------------------------------ the form -- */

.auth-layout{
  position:relative;
  z-index:1;
  flex:1;
  width:100%;
  max-width:var(--shell-max);
  margin:0 auto;
  display:grid;
  gap:clamp(2rem,5vw,3rem);
  align-content:center;
  padding:clamp(2rem,5vh,3.5rem) max(var(--pad-x),18px) clamp(2.5rem,6vh,4rem);
  color:#f4f1ea;
}
@media (min-width:901px){
  .auth-layout{
    grid-template-columns:minmax(0,25rem) minmax(0,1fr);
    align-items:center;
  }
}
/* Onboarding is reached signed in, so below 901px the tab bar is fixed over
   the bottom of the window and only that case needs the room. */
@media (max-width:900px){
  .shell:has(.tabbar) .auth-layout{padding-bottom:calc(5.5rem + env(safe-area-inset-bottom))}
}

.auth-col{max-width:25rem;width:100%}

.auth-kicker{
  margin:0 0 .6rem;
  font-size:.7rem;
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:rgba(244,241,234,.52);
}
.auth-title{
  font-size:clamp(2.4rem,5vw,3.35rem);
  color:#f7f4ed;
}
.auth-title em{color:rgba(244,241,234,.6)}
.auth-sub{
  margin-bottom:1.6rem;
  max-width:34ch;
  color:rgba(244,241,234,.66);
}

/* Glass, not a slab.

   The first version of this was a pale card, which is the right thing on a
   pale page and the wrong thing here: on a night scene it reads as a login
   box that has been pasted over a photograph. So the card is the photograph,
   blurred — the record and the meadow carry on through it — and everything
   inside it turns to light-on-dark to match. */
.auth-card{
  position:relative;
  padding:clamp(1.15rem,2.4vw,1.6rem);
  border:1px solid rgba(255,255,255,.16);
  border-radius:16px;
  background:linear-gradient(180deg,rgba(18,21,26,.5),rgba(10,11,14,.62));
  backdrop-filter:blur(26px) saturate(150%);
  -webkit-backdrop-filter:blur(26px) saturate(150%);
  box-shadow:
    0 1px 0 rgba(255,255,255,.16) inset,
    0 40px 80px -40px rgba(0,0,0,.95);
  color:#f4f1ea;
}
/* Backdrop blur alone leaves the top edge invisible where the scene behind is
   already dark, so the pane gets its own glancing highlight. */
.auth-card::before{
  content:"";
  position:absolute;
  inset:0;
  border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(150deg,rgba(255,255,255,.1),rgba(255,255,255,0) 42%);
}
.auth-card > *{position:relative}

.auth-card .field:last-of-type{margin-bottom:1.15rem}
.auth-card label{color:rgba(244,241,234,.92)}
.auth-card .field-hint,
.auth-card .muted{color:rgba(244,241,234,.56)}
.auth-card a{color:#f4f1ea}
.auth-card strong{color:#fff}

/* The fields. Wells cut into the glass rather than white boxes sitting on it. */
.auth-card .input,
.auth-card .textarea,
.auth-card .select{
  background:rgba(255,255,255,.07);
  border-color:rgba(255,255,255,.2);
  color:#f7f4ed;
}
.auth-card .input::placeholder,
.auth-card .textarea::placeholder{color:rgba(244,241,234,.36)}
.auth-card .input:hover,
.auth-card .textarea:hover,
.auth-card .select:hover{border-color:rgba(255,255,255,.34)}
.auth-card .input:focus,
.auth-card .textarea:focus,
.auth-card .select:focus{
  border-color:rgba(255,255,255,.62);
  background:rgba(255,255,255,.12);
  box-shadow:0 0 0 3px rgba(255,255,255,.1);
}

/* Chrome paints its own opaque cream over an autofilled field, which would
   punch a bright rectangle through the glass. The inset shadow is the only
   way to override it. */
.auth-card .input:-webkit-autofill,
.auth-card .input:-webkit-autofill:hover,
.auth-card .input:-webkit-autofill:focus{
  -webkit-text-fill-color:#f7f4ed;
  -webkit-box-shadow:0 0 0 1000px rgba(26,30,36,.97) inset;
  caret-color:#f7f4ed;
}

/* Ink on ink is invisible, so the submit button inverts with everything else. */
.auth-card .btn{background:#f4f1ea;color:#0b0b0c}
.auth-card .btn:hover{background:#fff;box-shadow:0 12px 28px -14px rgba(0,0,0,.9)}
.auth-card .btn .spinner{border-color:rgba(11,11,12,.3);border-top-color:#0b0b0c}

/* --danger is a deep brick that disappears against this. */
.auth-card .field-error{color:#f0938a}
.auth-card .input[aria-invalid="true"],
.auth-card .textarea[aria-invalid="true"]{border-color:rgba(240,147,138,.7)}
.auth-card .banner-danger{
  border-color:rgba(240,147,138,.4);
  background:rgba(154,47,40,.24);
  color:#f7d8d4;
}
.auth-card .banner-danger strong{color:#fff}

/* ------------------------------------------------- setup: wallet step -- */
/* The wallet panels were built for the light app and are reused here as they
   are, so everything below only re-lights them for the glass. None of it
   reaches outside .auth-card. */

.auth-card .card{
  padding:0;
  border:0;
  background:none;
  backdrop-filter:none;
  -webkit-backdrop-filter:none;
}
.auth-card .card + .card{margin-top:0}

/* Secondary buttons. The rule above turns every .btn cream so the submit
   stands out; a row of cream MetaMask/Phantom/Lock buttons would all shout at
   once, so the quiet ones go back to being glass. */
.auth-card .btn-ghost,
.auth-card .btn-quiet{
  background:rgba(255,255,255,.07);
  color:#f4f1ea;
  border:1px solid rgba(255,255,255,.2);
}
.auth-card .btn-ghost:hover,
.auth-card .btn-quiet:hover{
  background:rgba(255,255,255,.14);
  border-color:rgba(255,255,255,.34);
}
.auth-card .btn-ghost svg,
.auth-card .btn-quiet svg{width:16px;height:16px}

.auth-card .banner-warn{
  border-color:rgba(255,255,255,.18);
  background:rgba(255,255,255,.06);
  color:#f4f1ea;
}
.auth-card .receive-address{
  background:rgba(255,255,255,.06);
  border-color:rgba(255,255,255,.14);
  color:#f7f4ed;
}
.auth-card .status{
  background:rgba(255,255,255,.06);
  border-color:rgba(255,255,255,.2);
  color:rgba(244,241,234,.7);
}
.auth-card .status-completed{color:#8fd4bb;border-color:rgba(143,212,187,.35)}

.auth-card details.advanced summary{color:rgba(244,241,234,.6)}
.auth-card details.advanced summary:hover{color:#f4f1ea}

/* The native dropdown list is drawn by the OS on white, so its options need
   their own dark text or they are cream on white. */
.auth-card select option{color:#0b0b0c;background:#fff}

/* "or connect one you already use" — a hairline with words in it. */
.auth-or{
  display:flex;
  align-items:center;
  gap:12px;
  margin:22px 0 14px;
  font-size:.72rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:rgba(244,241,234,.45);
}
.auth-or::before,
.auth-or::after{
  content:"";
  flex:1;
  height:1px;
  background:rgba(255,255,255,.14);
}

.auth-connect{flex-wrap:wrap}
.auth-connect .muted{margin:0}

/* Skipping is a real option, so it is a real button — just not a loud one. */
.auth-skip{
  display:block;
  width:100%;
  margin-top:18px;
  padding:10px 0 2px;
  border-top:1px solid rgba(255,255,255,.1);
  font-size:.84rem;
  color:rgba(244,241,234,.55);
  text-align:center;
  cursor:pointer;
  transition:color .3s var(--ease);
}
.auth-skip:hover{color:#f4f1ea}

/* -------------------------------------------------- setup: name step -- */
/* The whole point of the step in one line: the name, and where it goes. */

.auth-handle{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:8px;
  margin-bottom:18px;
  padding:12px 14px;
  border-radius:10px;
  border:1px solid rgba(255,255,255,.14);
  background:rgba(255,255,255,.05);
  font-size:.9rem;
  color:rgba(244,241,234,.7);
}
.auth-handle strong{
  color:#f7f4ed;
  font-weight:500;
  font-size:1rem;
}
.auth-handle__arrow{color:#c69648}
.auth-handle .mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.82rem}

/* ------------------------------------------------------------ the pitch -- */

.auth-pitch{max-width:26ch}
@media (min-width:901px){
  .auth-pitch{justify-self:start}
}

.auth-pitch__line{
  margin:0 0 1rem;
  font-family:var(--display);
  font-weight:400;
  font-size:clamp(1.45rem,2.4vw,2rem);
  line-height:1.15;
  letter-spacing:-.012em;
  text-wrap:balance;
}

.auth-pitch__points{
  margin:0;
  padding:0;
  list-style:none;
  display:flex;
  flex-direction:column;
  gap:.45rem;
  font-size:.88rem;
  color:rgba(244,241,234,.74);
}
.auth-pitch__points li{display:flex;align-items:center;gap:.6rem}
.auth-pitch__points li::before{
  content:"";
  flex:none;
  width:5px;
  height:5px;
  border-radius:50%;
  background:#c69648;
}

@media (prefers-reduced-motion:reduce){
  .auth-disc,.auth-disc__sheen{animation:none}
}

/* A footnote under the receive warning: the four tokens whose real on-chain
   ticker is not the one everybody calls them by. */
.receive-alias{
  margin:-.4rem 0 .8rem;
  font-size:.74rem;
  line-height:1.5;
  color:var(--muted);
}

/* ------------------------------------------------------- adding people -- */

.add-people__row{display:flex;gap:8px}
.add-people__row .input{flex:1;min-width:0}
.add-people__row .btn{flex:none}
.add-people__note{
  margin:12px 0 0;
  font-size:.86rem;
  line-height:1.6;
  color:var(--muted);
}
.add-people .list-item{margin-top:10px}

.your-card__name{
  font-family:var(--display);
  font-size:clamp(2rem,4vw,2.8rem);
  line-height:1;
  letter-spacing:-.02em;
  margin-bottom:8px;
}
.your-card__line{
  margin:0 0 14px;
  font-size:.88rem;
  line-height:1.6;
  color:var(--muted);
  max-width:60ch;
}
.your-card .receive-address{margin-bottom:10px}

.add-people__toggle{
  display:flex;
  gap:12px;
  align-items:flex-start;
  margin-top:18px;
  padding-top:16px;
  border-top:1px solid var(--line-soft);
  cursor:pointer;
}
.add-people__switch{width:18px;height:18px;margin-top:2px;flex:none;accent-color:var(--ink)}
.add-people__toggle-title{display:block;font-size:.95rem}
.add-people__toggle-hint{display:block;margin-top:4px;font-size:.8rem;line-height:1.55;color:var(--muted)}
.add-people__toggle--compact{margin:4px 0 18px}
.add-people__toggle--compact .add-people__toggle{margin-top:0;padding-top:14px}
/* On the dark sign-up card. */
.auth-card .add-people__toggle{border-top-color:rgba(244,241,234,.16)}
.auth-card .add-people__switch{accent-color:#E8E3D0}
.auth-card .add-people__toggle-title{color:rgba(244,241,234,.92)}
.auth-card .add-people__toggle-hint{color:rgba(244,241,234,.6)}

/* ================================================================ menu == */
/* One button for search, notifications and settings, in the reference's
   shape, opening onto a staircase of forest columns. Colours fall back to
   fixed values so the menu still works with theme.css removed. */

.k-menu-btn{
  --r:9px;
  position:relative;
  display:grid;
  place-items:center;
  width:44px;
  height:44px;
  flex:none;
  border:0;
  padding:0;
  cursor:pointer;
  background:var(--moss, #2F5443);
  color:var(--cream, #E8E3D0);
  /* Four quarter-circles bitten out of the corners: each quadrant is its own
     radial gradient, transparent inside the bite and solid outside it. */
  -webkit-mask:
    radial-gradient(circle var(--r) at 0 0, #0000 98%, #000) 0 0 / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 100% 0, #0000 98%, #000) 100% 0 / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 0 100%, #0000 98%, #000) 0 100% / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #0000 98%, #000) 100% 100% / 51% 51% no-repeat;
  mask:
    radial-gradient(circle var(--r) at 0 0, #0000 98%, #000) 0 0 / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 100% 0, #0000 98%, #000) 100% 0 / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 0 100%, #0000 98%, #000) 0 100% / 51% 51% no-repeat,
    radial-gradient(circle var(--r) at 100% 100%, #0000 98%, #000) 100% 100% / 51% 51% no-repeat;
  transition:background-color .35s var(--ease);
}
.k-menu-btn:hover{background:var(--ink, #0C2E22)}
.k-menu-btn:focus-visible{outline:none;background:var(--ink, #0C2E22)}

.k-menu-btn__lines{position:relative;width:18px;height:8px}
.k-menu-btn__lines span{
  position:absolute;
  left:0;
  width:100%;
  height:1.5px;
  border-radius:1px;
  background:currentColor;
  transition:transform .5s var(--ease-in-out), top .5s var(--ease-in-out);
}
.k-menu-btn__lines span:nth-child(1){top:0}
.k-menu-btn__lines span:nth-child(2){top:6.5px}

/* The same button inside the open menu, with its two lines crossed. */
.k-menu-btn--close{background:var(--cream, #E8E3D0);color:var(--forest, #17291F)}
.k-menu-btn--close:hover{background:#fff}
.k-menu.is-open .k-menu-btn--close .k-menu-btn__lines span:nth-child(1){top:3.25px;transform:rotate(45deg)}
.k-menu.is-open .k-menu-btn--close .k-menu-btn__lines span:nth-child(2){top:3.25px;transform:rotate(-45deg)}

.k-menu-btn__dot{
  position:absolute;
  top:8px;
  right:8px;
  width:7px;
  height:7px;
  border-radius:50%;
  background:#E3A24B;
  box-shadow:0 0 0 2px var(--moss, #2F5443);
}

body.k-menu-open{overflow:hidden}

.k-menu{
  position:fixed;
  inset:0;
  z-index:150;
  display:flex;
  flex-direction:column;
  padding:14px max(var(--pad-x), 16px) 26px;
  color:var(--cream, #E8E3D0);
  overflow-y:auto;
}

/* The staircase. Columns scale down from the top one after another, and on
   the way out go back up in reverse, so the last to arrive leaves first. */
.k-menu__cols{
  position:fixed;
  inset:0;
  z-index:-1;
  display:grid;
  grid-template-columns:repeat(6, 1fr);
}
.k-menu__col{
  background:var(--forest, #17291F);
  /* Each column is animated on its own layer, and the anti-aliased edges
     between six of them showed as thin light seams. They overlap their
     neighbour by two pixels instead, so there is never a gap to see. */
  width:calc(100% + 2px);
  transform:scaleY(0);
  transform-origin:top;
  transition:transform .7s var(--ease-in-out);
  transition-delay:calc(var(--c) * 55ms);
}
.k-menu.is-open .k-menu__col{transform:scaleY(1)}
.k-menu.is-closing .k-menu__col{transition-delay:calc((5 - var(--c)) * 55ms)}

.k-menu__top,
.k-menu__foot{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
}
.k-menu__top{min-height:44px}
.k-menu__foot{margin-top:auto;padding-top:28px}
.k-menu__kicker{
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:rgba(232,227,208,.55);
  opacity:0;
  transition:opacity .4s ease .45s;
}
.k-menu.is-open .k-menu__kicker{opacity:1}
.k-menu.is-closing .k-menu__kicker{transition-delay:0s}

.k-menu__list{
  width:100%;
  max-width:var(--shell-max, 1180px);
  margin:clamp(24px,6vh,64px) auto 0;
  border-top:1px solid rgba(232,227,208,.16);
}

/* Each row arrives out of focus, after the columns, one after another. */
.k-menu__item{
  display:grid;
  grid-template-columns:44px 1fr auto 28px;
  align-items:baseline;
  gap:14px;
  padding:clamp(12px,2.2vh,20px) 0;
  border-bottom:1px solid rgba(232,227,208,.16);
  color:var(--cream, #E8E3D0);
  text-decoration:none;
  opacity:0;
  filter:blur(10px);
  transform:translate3d(0,14px,0);
}
.k-menu.is-open .k-menu__item,
.k-menu.is-open .k-menu__signout{
  animation:kMenuIn .8s var(--ease) both;
  animation-delay:calc(380ms + var(--i) * 65ms);
}
.k-menu.is-closing .k-menu__item,
.k-menu.is-closing .k-menu__signout{
  opacity:0;
  filter:blur(8px);
  transition:opacity .25s ease, filter .25s ease;
}
@keyframes kMenuIn{
  from{ opacity:0; filter:blur(10px); transform:translate3d(0,14px,0) }
  to  { opacity:1; filter:none;       transform:none }
}

.k-menu__num{
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10px;
  letter-spacing:.1em;
  color:rgba(232,227,208,.5);
}
.k-menu__label{
  font-family:var(--ui, sans-serif);
  font-size:clamp(2rem,5.2vw,3.6rem);
  line-height:1;
  letter-spacing:-.05em;
  transition:transform .5s var(--ease), color .3s ease;
}
.k-menu__count{
  display:inline-grid;
  place-items:center;
  min-width:1.6em;
  height:1.6em;
  margin-left:.5em;
  padding:0 .4em;
  vertical-align:.9em;
  border-radius:999px;
  background:#E3A24B;
  color:var(--forest, #17291F);
  font-family:var(--mono, ui-monospace, monospace);
  font-size:.24em;
  letter-spacing:0;
}
.k-menu__meta{
  font-size:.82rem;
  color:rgba(232,227,208,.55);
  text-align:right;
}
.k-menu__arrow{
  font-size:1.1rem;
  color:rgba(232,227,208,.7);
  transition:transform .45s var(--ease);
}
.k-menu__item:hover .k-menu__label,
.k-menu__item:focus-visible .k-menu__label{transform:translateX(10px)}
.k-menu__item:hover .k-menu__arrow,
.k-menu__item:focus-visible .k-menu__arrow{transform:translate(3px,-3px);color:var(--cream, #E8E3D0)}
.k-menu__item:focus-visible{outline:none}

.k-menu__signout{
  border:1px solid rgba(232,227,208,.3);
  padding:10px 16px;
  color:var(--cream, #E8E3D0);
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10.5px;
  letter-spacing:.14em;
  text-transform:uppercase;
  cursor:pointer;
  opacity:0;
  transition:background-color .3s ease;
}
.k-menu__signout:hover{background:rgba(232,227,208,.1)}

@media (max-width:640px){
  .k-menu__item{grid-template-columns:32px 1fr 22px}
  .k-menu__meta{display:none}
}

@media (prefers-reduced-motion:reduce){
  .k-menu__col{transition:none}
  .k-menu.is-open .k-menu__item,
  .k-menu.is-open .k-menu__signout{animation:none;opacity:1;filter:none;transform:none}
}

/* ======================================================== rolling logo == */
/* The name and the mark, large, sliding past between two hairlines. Colour
   comes from where it is put: cream on the sign-in scene, forest on paper. */

.k-roll{
  overflow:hidden;
  white-space:nowrap;
  font-size:clamp(3.6rem,11vw,10rem);
  line-height:1.08;
  padding:.06em 0 .02em;
  border-top:1px solid color-mix(in srgb, currentColor 20%, transparent);
  border-bottom:1px solid color-mix(in srgb, currentColor 20%, transparent);
  user-select:none;
}
/* Every item carries its own trailing space, and the track has no gap: that
   keeps the two halves exactly equal, so sliding one half is seamless. */
.k-roll__track{
  display:inline-flex;
  align-items:center;
  animation:kRoll 38s linear infinite;
}
.k-roll__track > *{margin-right:.26em;flex:none}
@keyframes kRoll{ to{ transform:translateX(-50%) } }

.k-roll__serif{
  position:relative;
  font-family:var(--display, Georgia, serif);
  font-weight:400;
  letter-spacing:-.02em;
}
.k-roll__index{
  position:absolute;
  top:.12em;
  right:-1.35em;
  font-family:var(--ui, sans-serif);
  font-size:.13em;
  letter-spacing:0;
  opacity:.8;
}
.k-roll__serif{margin-right:.5em}
.k-roll__name{
  font-family:var(--ui, sans-serif);
  font-weight:500;
  letter-spacing:-.065em;
}
.k-roll__dash{font-family:var(--ui, sans-serif);font-weight:300}
.k-roll__mark{
  width:.74em;
  height:.74em;
  background:currentColor;
  clip-path:polygon(0 0, 58% 0, 100% 42%, 100% 100%, 42% 100%, 0 58%);
}

/* On a page, the band runs edge to edge rather than inside the column. */
.k-roll-bleed{margin:44px calc(50% - 50vw) 36px;color:var(--ink)}

@media (prefers-reduced-motion:reduce){
  .k-roll__track{animation:none}
}

/* ========================================================== about us == */
/* Under the sign-in form: a dark panel that slides up over the record. */

.auth-stage{flex-direction:column}
.auth-stage:has(.auth-after) .auth-layout{min-height:calc(100svh - 64px)}
.auth-after{position:relative;z-index:1;width:100%}

.auth-scroll-cue{
  position:absolute;
  left:50%;
  bottom:18px;
  transform:translateX(-50%);
  padding:8px 12px;
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:rgba(244,240,228,.6);
  cursor:pointer;
  transition:color .3s ease;
  animation:kNudge 2.4s var(--ease-in-out) infinite;
}
.auth-scroll-cue:hover{color:#F4F0E4}
@keyframes kNudge{ 0%,100%{ translate:0 0 } 50%{ translate:0 4px } }

.k-about{
  color:#F4F0E4;
  background:rgba(10,22,16,.9);
  backdrop-filter:blur(20px) saturate(120%);
  -webkit-backdrop-filter:blur(20px) saturate(120%);
  padding-bottom:clamp(56px,10vh,110px);
}
.k-about__inner{
  max-width:var(--shell-max, 1180px);
  margin:0 auto;
  padding:clamp(44px,8vh,90px) max(var(--pad-x), 18px) 0;
}
.k-about__kicker{
  margin:0 0 18px;
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:rgba(244,240,228,.55);
}
.k-about__line{
  margin:0 0 22px;
  max-width:17ch;
  font-family:var(--display, Georgia, serif);
  font-weight:400;
  font-size:clamp(2.5rem,5.4vw,4.6rem);
  line-height:1;
  letter-spacing:-.02em;
}
.k-about__lede{
  margin:0 0 42px;
  max-width:52ch;
  font-size:clamp(1rem,1.45vw,1.2rem);
  line-height:1.55;
  color:rgba(244,240,228,.78);
}
.k-about__rows{border-top:1px solid rgba(244,240,228,.16)}
.k-about__row{
  display:grid;
  grid-template-columns:44px minmax(0,1fr) minmax(0,1.3fr);
  gap:16px;
  align-items:baseline;
  padding:clamp(14px,2.4vh,22px) 0;
  border-bottom:1px solid rgba(244,240,228,.16);
}
.k-about__num{
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10px;
  letter-spacing:.1em;
  color:rgba(244,240,228,.5);
}
.k-about__name{
  font-family:var(--ui, sans-serif);
  font-size:clamp(1.55rem,2.8vw,2.3rem);
  line-height:1.05;
  letter-spacing:-.05em;
}
.k-about__desc{font-size:.93rem;line-height:1.55;color:rgba(244,240,228,.66)}
.k-about__not{margin-top:clamp(40px,7vh,72px)}
.k-about__not .k-about__lede{margin-bottom:0}
.k-about__more{
  display:inline-block;
  margin-top:30px;
  padding-bottom:4px;
  border-bottom:1px solid rgba(244,240,228,.4);
  font-family:var(--mono, ui-monospace, monospace);
  font-size:10.5px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:#F4F0E4;
  text-decoration:none;
}
.k-about__more:hover{border-bottom-color:#F4F0E4}

@media (max-width:640px){
  .k-about__row{grid-template-columns:32px minmax(0,1fr)}
  .k-about__desc{grid-column:2}
}

/* ---------------------------------------------------- recovery phrase -- */
/* Numbered, in order, in a grid you copy onto paper row by row. */

.phrase-grid{
  list-style:none;
  counter-reset:phrase;
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:6px;
  margin:12px 0 0;
  padding:0;
}
.phrase-grid li{
  counter-increment:phrase;
  display:flex;
  align-items:baseline;
  gap:8px;
  padding:9px 10px;
  border:1px solid var(--line-soft);
  background:var(--surface-2, transparent);
  font-family:var(--mono, ui-monospace, monospace);
  font-size:.9rem;
  min-width:0;
}
.phrase-grid li::before{
  content:counter(phrase);
  font-size:.7rem;
  color:var(--muted);
  min-width:1.4em;
  text-align:right;
}
.phrase-grid__word{overflow-wrap:anywhere;user-select:all}
@media (max-width:420px){.phrase-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}

.phrase-key{margin-top:12px;font-size:.85rem}
.phrase-key summary{cursor:pointer;color:var(--muted)}
.quix-addr__label{
  font-family:var(--mono, ui-monospace, monospace);
  font-size:.68rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--muted);
  margin:0 0 6px;
}

/* The undo window: the confirm button counting down. Quiet colours on
   purpose — this is the moment to notice a mistake, not to be rushed. */
.btn.btn-undo{
  background:transparent;
  color:var(--ink);
  border:1px solid var(--ink);
  font-variant-numeric:tabular-nums;
}

/* ------------------------------------------------------- people strip -- */
/* The last few people you paid, as faces. Scrolls sideways on a phone. */
.people-strip{margin:18px 0 6px}
.people-strip__label{
  font-family:var(--mono, ui-monospace, monospace);
  font-size:.7rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--muted);
  margin-bottom:10px;
}
.people-strip__row{
  display:flex;
  gap:14px;
  overflow-x:auto;
  padding-bottom:4px;
  scrollbar-width:none;
}
.people-strip__row::-webkit-scrollbar{display:none}
.people-strip__person{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  flex:none;
  width:64px;
  padding:0;
  border:0;
  background:none;
  color:inherit;
  font:inherit;
  cursor:pointer;
}
.people-strip__person .avatar{transition:transform .2s ease}
.people-strip__person:hover .avatar,
.people-strip__person:focus-visible .avatar{transform:translateY(-2px)}
.people-strip__name{
  font-size:.78rem;
  max-width:64px;
  overflow:hidden;
  text-overflow:ellipsis;
  white-space:nowrap;
}

/* ------------------------------------------------------ profile picture -- */
.avatar-xl{width:88px;height:88px;font-size:1.7rem}
.profile-pic{display:flex;align-items:center;gap:18px;flex-wrap:wrap}

/* An X link: the logo and the @handle, quiet until hovered. */
.x-link{
  display:inline-flex;
  align-items:center;
  gap:7px;
  padding:6px 12px;
  border:1px solid var(--line-soft);
  font-size:.86rem;
  color:var(--ink);
  text-decoration:none;
  transition:background .2s ease;
}
.x-link:hover{background:rgba(12,46,34,.06)}
.x-link__logo{width:13px;height:13px;flex:none}

/* Me, in the top bar: picture and @username, opening Settings. */
.me-chip{
  display:inline-flex;
  align-items:center;
  gap:9px;
  margin-right:12px;
  font-family:var(--mono, ui-monospace, monospace);
  font-size:.72rem;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink);
  text-decoration:none;
}
.me-chip .avatar{width:30px;height:30px;font-size:.66rem}
@media (max-width:560px){ .me-chip span{display:none} }

/* ---------------------------------------------------------------- chat --
   views/chat.js. Bubbles right for you, left for them; money between you
   sits in the same line of time as a card that opens its receipt. The
   composer stays at the bottom of the screen, above the phone's tab bar,
   and drops to the very bottom while the keyboard is up. */

.chat-head{display:flex;align-items:center;gap:10px;padding-bottom:12px;border-bottom:1px solid var(--line-soft)}
.chat-head__who{min-width:0;flex:1;text-decoration:none;color:inherit;cursor:pointer}
.chat-head__title{font-size:17px;letter-spacing:-.02em}
.chat-head__actions{display:flex;align-items:center;gap:6px;flex:none}
.chat-back{flex:none}
@media (max-width:520px){ .hide-narrow{display:none} }

.chat-log{display:flex;flex-direction:column;gap:2px;padding:14px 0 8px;min-height:calc(100dvh - 360px)}
.chat-day{align-self:center;margin:14px 0 8px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--quiet,var(--muted))}
.chat-empty{margin:auto;padding:48px 0;color:var(--muted);text-align:center}

.chat-msg{display:flex;flex-direction:column;max-width:min(78%,560px)}
.chat-msg--mine{align-self:flex-end;align-items:flex-end}
.chat-msg--theirs{align-self:flex-start;align-items:flex-start}
.chat-msg__who{font-size:12px;color:var(--muted);margin:8px 2px 3px}
.chat-bubble{
  padding:9px 13px;font-size:15px;line-height:1.42;
  white-space:pre-wrap;overflow-wrap:anywhere;
  border:1px solid var(--line-soft);background:var(--surface-hi);
  border-radius:calc(var(--radius) + 4px);
}
.chat-msg--mine .chat-bubble{background:var(--ink);color:var(--cream,#f4f1ea);border-color:var(--ink);cursor:pointer}
.chat-msg__meta{display:flex;align-items:center;gap:8px;margin:3px 2px 6px;font-family:var(--mono);font-size:10.5px;color:var(--quiet,var(--muted))}
.chat-unsend{display:none;background:none;border:0;padding:4px 2px;font:inherit;color:var(--danger);text-decoration:underline;cursor:pointer}
.chat-msg.is-open .chat-unsend{display:inline}
@media (hover:hover){ .chat-msg--mine:hover .chat-unsend{display:inline} }

.chat-money{
  align-self:flex-start;display:flex;flex-direction:column;gap:4px;
  min-width:220px;max-width:min(78%,420px);margin:8px 0;padding:12px 14px;
  border:1px solid var(--line);background:var(--paper,var(--surface-hi));color:inherit;text-decoration:none;
  border-radius:calc(var(--radius) + 4px);
}
.chat-money--mine{align-self:flex-end}
.chat-money:hover{border-color:var(--ink)}
.chat-money__label{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.chat-money__amount{font-size:22px;letter-spacing:-.02em}
.chat-money__note{font-size:13px;color:var(--muted);font-style:italic}
.chat-money__foot{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10.5px;color:var(--muted)}
.chat-money__cta{color:var(--ink);font-weight:500}

.chat-composer-host{position:sticky;bottom:0;z-index:5;background:var(--sky);padding:10px 0 12px;border-top:1px solid var(--line-soft)}
.chat-composer{display:flex;align-items:flex-end;gap:8px}
.chat-input{
  flex:1;min-width:0;min-height:46px;max-height:160px;resize:none;
  padding:12px 14px;font:inherit;font-size:16px;line-height:1.35;color:inherit;
  border:1px solid var(--line);background:var(--surface-hi);border-radius:calc(var(--radius) + 4px);
}
.chat-input:focus{outline:none;border-color:var(--ink)}
.chat-send{flex:none;min-width:48px;min-height:46px;padding:0 14px}
.chat-closed{text-align:center;padding:10px 0;margin:0}
@media (max-width:900px){
  .chat-composer-host{bottom:calc(58px + env(safe-area-inset-bottom))}
  body.kb-open .chat-composer-host{bottom:0}
  /* The composer is the bottom of a chat: no tab-bar-sized gap under it. */
  .main:has(.chat-page){padding-bottom:calc(58px + env(safe-area-inset-bottom))}
  body.kb-open .main:has(.chat-page){padding-bottom:0}
}

.chat-row--unread .list-title{font-weight:600}
.chat-count{min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--ink);color:var(--cream,#f4f1ea);font-size:11px;line-height:20px;text-align:center}
.chat-tag{margin-right:6px;padding:1px 5px;border:1px solid var(--line);font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;text-transform:uppercase;vertical-align:2px;color:var(--muted)}
.chat-avatar--group{background:var(--moss,#2F5443);color:var(--cream,#f4f1ea)}

.chip-row{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:3px 10px 3px 3px;border:1px solid var(--line);background:var(--surface-hi);font:inherit;font-size:13px;color:inherit;cursor:pointer;border-radius:calc(var(--radius) + 18px)}
.chip svg{width:14px;height:14px;opacity:.6}

.tab-badge{position:absolute;top:6px;left:calc(50% + 5px);min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--danger);color:#fff;font-size:10px;line-height:16px;letter-spacing:0;text-align:center}
@media (min-width:901px){ .tab-badge{top:5px;left:auto;right:2px} }

.joined-row{display:flex;align-items:center;gap:8px}
.joined-row > .list-item{flex:1;min-width:0}
.joined-row__leave{flex:none}
.member-banner{margin-bottom:14px}
.friend-gate{padding:18px;border:1px solid var(--line);background:var(--surface-hi);text-align:center;border-radius:calc(var(--radius) + 4px)}
.friend-gate__title{margin:0 0 6px;font-size:16px;letter-spacing:-.01em}
.friend-gate .muted{margin:0 auto 14px;max-width:44ch;font-size:13.5px;line-height:1.55}
.chat-composer-host .friend-gate{margin:0}

/* ------------------------------------------------ two-step and the lock --
   views/two-step.js and ui/lock.js. */
.two-step__state{margin:0 0 4px;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.two-step__state--on{color:var(--positive)}
.two-step__text{margin:0 0 14px;font-size:13.5px;line-height:1.6;max-width:56ch}
.two-step__steps{margin:0 0 12px;padding-left:20px;line-height:1.6;font-size:14px}
.two-step__qr{display:grid;place-items:center;padding:14px;background:#fff;margin:0 auto 12px;max-width:240px}
.two-step__qr svg{width:100%;height:auto}
.two-step__key{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.two-step__key code{font-size:14px;letter-spacing:.06em;word-break:break-all}
.two-step__code{font-size:22px;letter-spacing:.3em;text-align:center}
.two-step-nudge{margin:16px 0 0}
.link-btn{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer}

.k-menu__foot-actions{display:flex;gap:18px}

html.is-locked body{overflow:hidden}
dialog.lock{
  position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;border:0;padding:16px;
  display:grid;place-items:center;background:var(--sky,#E7E3D2);color:var(--ink,#0C2E22);
}
dialog.lock::backdrop{background:var(--sky,#E7E3D2)}
.lock__card{width:min(360px,100%);display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}
.lock__mark{margin-bottom:4px}
.lock__title{margin:0;font-family:var(--serif,"Instrument Serif",serif);font-weight:400;font-size:2.2rem;letter-spacing:-.02em}
.lock__who{display:flex;flex-direction:column;align-items:center;gap:8px;min-height:24px;font-size:14px;color:var(--muted)}
.lock__form{width:100%;display:grid;gap:10px;margin-top:6px}
.lock__form .input{font-size:16px;text-align:center}
.lock__error{margin:0;color:var(--danger);font-size:13px}
.lock__out{background:none;border:0;color:var(--muted);font:inherit;font-size:13px;text-decoration:underline;cursor:pointer;padding:8px}

/* PayMate on X (ui/components.js followOnX) and copying the 12 words. */
.x-follow{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-width:44px;min-height:44px;color:inherit;text-decoration:none}
.x-follow svg{width:18px;height:18px}
.x-follow:hover{opacity:.7}
.k-menu__x{min-width:auto;min-height:auto;color:inherit}
.phrase-copy-row{margin:14px 0 4px}
.phrase-copy__note{margin:8px 0 0;font-size:12.5px;line-height:1.55;max-width:52ch}
