/* Yamale — the shared visual system.
 *
 * One source of truth for the things every surface gets wrong independently:
 * typefaces, the type scale, elevation, and the semantic colours. The palette
 * itself (navy, ink, brass, paper, mist, slate) was already consistent across
 * the clients; what was missing was everything around it.
 *
 * Three faces, and the choice is constrained rather than tasteful:
 *
 *   IBM Plex Sans        body and interface
 *   IBM Plex Sans Arabic the same, for ar
 *   Archivo              display
 *   IBM Plex Mono        data — addresses, hashes, heights, amounts
 *
 * Plex is the load-bearing decision. This ships in Arabic and Swahili as well
 * as English, French and Portuguese, and Plex Sans Arabic is a *designed*
 * companion to Plex Sans rather than a fallback that happens to have the
 * glyphs — so an Arabic page keeps the same voice instead of looking like a
 * translation of somebody else's product. Plex was also drawn for technical
 * documentation, which is the register this needs. Archivo carries the display
 * line: a grotesque with signage lineage that tightens properly at large sizes
 * and does not read as the default that ships with every dashboard.
 *
 * WHY THIS FILE EXISTS AT ALL: every surface here previously set
 * `--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI"`, so the
 * product's headline was rendered in whatever face the reader's operating
 * system happened to install. That is the single largest reason it read as a
 * draft rather than as infrastructure a central bank would run.
 */

/* --------------------------------------------------------------- typefaces */
/* Google Fonts is loaded by each surface's HTML rather than @import here, so
   the request starts before this stylesheet has parsed. The fallback stacks
   below still name real faces: a blocked font host must degrade to something
   chosen, not to Times. */

:root {
  --font-display: Archivo, 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-sans: 'IBM Plex Sans', 'IBM Plex Sans Arabic', system-ui, -apple-system,
    'Segoe UI', Roboto, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* A scale, so a page cannot invent a size. Ratio ~1.25, clamped where a
     heading has to survive a phone and a boardroom projector. */
  --step--1: 0.8125rem;
  --step-0: 0.9375rem;
  --step-1: 1.0625rem;
  --step-2: 1.25rem;
  --step-3: clamp(1.4rem, 2.2vw, 1.6rem);
  --step-4: clamp(1.75rem, 3.2vw, 2.15rem);
  --step-5: clamp(2.1rem, 4.6vw, 3rem);
  --step-6: clamp(2.5rem, 6vw, 3.9rem);

  /* Spacing on a 4px grid. Layout uses gap, not stacked margins. */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4.5rem;

  --radius: 5px;
  --radius-lg: 8px;
  --measure: 68ch;

  /* ------------------------------------------------------------- palette */
  /* Brand, unchanged — it was already right and already consistent. */
  --navy: #12253f;
  --ink: #0b1523;
  --brass: #a87b3c;
  --paper: #f6f7f9;
  --mist: #e3e7ee;
  --slate: #5c6e88;

  /* Light is the default so that the un-stamped, system-preference state
     resolves without a media query having to fire first. */
  --bg: var(--paper);
  --surface: #ffffff;
  --surface-2: #f1f4f8;
  --surface-3: #e9eef5;
  --border: var(--mist);
  --rule: #d3dae6;

  --text: var(--ink);
  --text-muted: #526178;
  --text-faint: #8798af;
  --accent: var(--navy);
  --accent-ink: #ffffff;
  --focus: #1f6feb;

  --ok: #0c6d42;
  --warn: #a8791b;
  --bad: #ac2924;
  --wash-ok: rgba(13, 122, 74, .10);
  --wash-warn: rgba(168, 121, 27, .12);
  --wash-bad: rgba(176, 42, 37, .10);
  --wash-mute: rgba(92, 110, 136, .10);
  --wash-brass: rgba(168, 123, 60, .12);

  /* Brass and amber are brand colours before they are type, and as type neither
     clears 4.5:1 in the light palette. Measured in a browser at 1600px:
     3.77:1 for a brass link on white, 3.31:1 for a brass chip on its own wash,
     3.38:1 for an amber chip on its own. Darkened along the same hue rather
     than replaced, and used only where the colour carries words — a border or a
     rule at 3.3:1 is doing a different job and reads correctly there. The dark
     palette needs no equivalent: both already pass, also measured. */
  --brass-ink: #78582b;
  --warn-ink: #795814;

  /* Elevation the palette previously had none of: every panel was a 1px
     border on flat white, which is why the surfaces read as wireframes. */
  --shadow-1: 0 1px 2px rgba(11, 21, 35, .06), 0 1px 1px rgba(11, 21, 35, .04);
  --shadow-2: 0 2px 6px rgba(11, 21, 35, .07), 0 8px 24px rgba(11, 21, 35, .05);
}

/* Dark, for the two states that reach it: the explicit choice below, and the
   system preference here. Only tokens are redefined — never a component rule,
   because a colour whose sole definition sits inside a media query never
   applies in the un-stamped state. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: var(--ink);
    --surface: #101f34;
    --surface-2: #162943;
    --surface-3: #1d3352;
    --border: #24405f;
    --rule: #2c4a6b;

    --text: #e8eef7;
    --text-muted: #8fa4c4;
    --text-faint: #6b83a6;
    --accent: #4d8fd6;
    --accent-ink: #08111d;
    --brass: #c49856;
    --focus: #6ea8ff;

    --ok: #6fbfa5;
    --warn: #d2a65e;
    --bad: #ef8a85;
    --wash-ok: rgba(111, 191, 165, .12);
    --wash-warn: rgba(210, 166, 94, .14);
    --wash-bad: rgba(239, 138, 133, .13);
    --wash-mute: rgba(143, 164, 196, .12);
    --wash-brass: rgba(196, 152, 86, .16);
    --brass-ink: #c79d5e;
    --warn-ink: var(--warn);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-2: 0 2px 8px rgba(0, 0, 0, .4), 0 12px 32px rgba(0, 0, 0, .3);
  }
}

:root[data-theme='dark'] {
  --bg: var(--ink);
  --surface: #101f34;
  --surface-2: #162943;
  --surface-3: #1d3352;
  --border: #24405f;
  --rule: #2c4a6b;

  --text: #e8eef7;
  --text-muted: #8fa4c4;
  --text-faint: #6b83a6;
  --accent: #4d8fd6;
  --accent-ink: #08111d;
  --brass: #c49856;
  --focus: #6ea8ff;

  --ok: #6fbfa5;
  --warn: #d2a65e;
  --bad: #ef8a85;
  --wash-ok: rgba(111, 191, 165, .12);
  --wash-warn: rgba(210, 166, 94, .14);
  --wash-bad: rgba(239, 138, 133, .13);
  --wash-mute: rgba(143, 164, 196, .12);
  --wash-brass: rgba(196, 152, 86, .16);
  --brass-ink: #c79d5e;
  --warn-ink: var(--warn);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, .4), 0 12px 32px rgba(0, 0, 0, .3);
}

/* ------------------------------------------------------------------- base */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  /* Explicit, because the artifact and preview hosts paint their own ground
     behind the page: a transparent body silently borrows the host's theme. */
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.018em;
  text-wrap: balance;
  margin: 0;
}

h1 { font-size: var(--step-6); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); letter-spacing: -0.01em; }
h4 { font-size: var(--step-1); letter-spacing: 0; }

p { margin: 0; max-width: var(--measure); }

/* Data is never set in the body face. An address, a hash, a height or an
   amount rendered in a proportional sans reads as prose, and the reader cannot
   compare two of them by eye — which on a payments network is the operation
   they perform most. */
code, kbd, samp, pre, .y-mono, .y-addr, .y-num {
  font-family: var(--font-mono);
  font-feature-settings: 'zero' 1;
}
.y-num, .y-tabular, td.y-num, th.y-num {
  font-variant-numeric: tabular-nums;
}
/* Tabular digits align a column only if the column is aligned. `.y-num` gave
   the digits equal width and left every cell ragged against a left edge, so a
   cap and the amount remaining under it could not be compared down the page —
   which is the only reason to put figures in a column at all.
   Scoped to table cells on purpose: `.y-num` is also on inline spans in four
   consoles, and right-aligning a number inside a sentence would be wrong. */
td.y-num, th.y-num { text-align: end; }
.y-addr { word-break: break-all; font-size: 0.88em; }

/* --------------------------------------------------------------- utilities */

.y-eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass-ink);
}

.y-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.y-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
}

/* State carried in form as well as in words, so what needs attention reads at
   a glance rather than on a second pass. */
.y-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.2rem 0.45rem;
  border-radius: 3px;
  white-space: nowrap;
}
.y-chip--ok { background: var(--wash-ok); color: var(--ok); }
.y-chip--warn { background: var(--wash-warn); color: var(--warn-ink); }
.y-chip--bad { background: var(--wash-bad); color: var(--bad); }
.y-chip--mute { background: var(--wash-mute); color: var(--text-muted); }
.y-chip--brass { background: var(--wash-brass); color: var(--brass-ink); }

/* Wide content scrolls inside its own box. The page body never scrolls
   sideways — a horizontal scrollbar on the document is how a table takes a
   whole layout with it. */
.y-scroll { overflow-x: auto; }

/* Keyboard focus is visible everywhere, once, from a token. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   INFORMATION DESIGN
   Added 2026-09-16, after the owner's verdict on the consoles: "this is just
   not looking good".

   The diagnosis was the same on every surface. Figures were set at the same
   size as their labels, so nothing read as a figure; everything lived in one
   scrolling column, so finding anything meant scrolling past everything; and
   data surfaces had no information design at all — a table of numbers with no
   alignment, no emphasis and no shape.

   These are the three patterns that fix it, defined ONCE here so eleven
   consoles do not invent eleven versions. Every colour is an existing token:
   this block adds layout and hierarchy, never a palette.
   ========================================================================== */

/* --- The figures a reader came for, before the prose explaining them ----- */

.y-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--sp-3);
  margin: var(--sp-4) 0 var(--sp-5);
}

.y-kpi {
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  border-inline-start: 3px solid var(--rule);
}
.y-kpi--ok   { border-inline-start-color: var(--ok); }
.y-kpi--warn { border-inline-start-color: var(--warn); }
.y-kpi--bad  { border-inline-start-color: var(--bad); }
.y-kpi--mute { border-inline-start-color: var(--text-faint); }

.y-kpi__label {
  margin: 0;
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.y-kpi__value {
  margin: var(--sp-1) 0 0;
  font-size: var(--step-2);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  /* A figure NEVER breaks across lines. `overflow-wrap: anywhere` shipped once
     and rendered 100,000,000 as "100,000,0" above "00" — a number split in two
     is not a smaller number, it is a different one. The unit may drop; the
     digits may not. */
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: normal;
}
.y-kpi__unit { margin-inline-start: 0.3em; font-size: var(--step-0); color: var(--text-muted); }

/* Where a figure's limit goes. Some are exact and some are not, and a band
   that spoke about all of them in one voice would claim a precision the chain
   does not have. Clamped, because a paragraph under every tile makes the band
   taller than the content it introduces. */
.y-kpi__hint {
  margin: var(--sp-2) 0 0;
  font-size: var(--step--1);
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* --- Folders, because one scrolling column is not a document ------------- */

.y-folders {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  border-bottom: 1px solid var(--rule);
  margin-bottom: var(--sp-4);
}
.y-folder {
  appearance: none;
  background: none;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: var(--sp-2) var(--sp-4);
  font: inherit;
  font-size: var(--step--1);
  color: var(--text-muted);
  cursor: pointer;
  /* The open folder sits ON the rule rather than above it, so the area below
     reads as the inside of the folder rather than as a separate box. */
  margin-bottom: -1px;
}
.y-folder:hover { color: var(--text); }
.y-folder[aria-selected='true'], .y-folder--on {
  background: var(--surface);
  border-color: var(--rule);
  border-bottom: 1px solid var(--surface);
  color: var(--text);
  font-weight: 600;
}
.y-folder__count { margin-inline-start: 0.45em; font-variant-numeric: tabular-nums; color: var(--text-faint); }

/* --- Data tables that can actually be read ------------------------------ */

.y-data { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.y-data th {
  text-align: start;
  font-size: var(--step--1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 600;
  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.y-data td {
  padding: var(--sp-2) var(--sp-3) var(--sp-2) 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: baseline;
}
/* Numbers right, words left.
   `padding-inline-end: 0` used to be unconditional here, which is right only
   for a LAST column: three numeric columns in the governance table are not
   last, and an id ran straight into the title beside it ("20A supply ceiling
   for the dollar"). The trailing padding is dropped only where there is
   nothing after it. */
.y-data .num, .y-data th.num { text-align: end; }
.y-data td.num:last-child, .y-data th.num:last-child { padding-inline-end: 0; }
.y-data tbody tr:hover { background: var(--surface-2); }
.y-data__self td { font-weight: 600; }
.y-data caption {
  caption-side: bottom;
  text-align: start;
  padding-top: var(--sp-2);
  font-size: var(--step--1);
  color: var(--text-muted);
}

/* Wide content scrolls INSIDE its own box; the page never scrolls sideways. */
.y-scrollx { overflow-x: auto; }

/* --- A proportion, drawn ------------------------------------------------- */

.y-ring { width: 100%; height: auto; max-width: 15rem; }
.y-ring__track { stroke: var(--surface-2); }

.y-split {
  display: grid;
  grid-template-columns: minmax(9rem, 15rem) 1fr;
  gap: var(--sp-5);
  align-items: start;
}
@media (max-width: 40rem) { .y-split { grid-template-columns: 1fr; } }

.y-swatch {
  display: inline-block;
  width: 0.7em; height: 0.7em;
  border-radius: 2px;
  margin-inline-end: 0.5em;
  vertical-align: baseline;
}

/* ========================================================================== */
/*  THE MOBILE SHELL                                                          */
/* ========================================================================== */
/*
 * A phone on a desk, for every surface a PERSON uses.
 *
 * Yamale Pay was designed as a phone and is the one surface here nobody has
 * complained about. The rest were laid out as dashboards — folders, KPI bands,
 * wide tables — which is the right shape for somebody supervising a registry at
 * a desk and the wrong one for somebody checking what they own on the way to
 * work. This is Pay's shape, extracted so the others can wear it.
 *
 * # Why a frame and not just a narrow column
 *
 * The frame is the point. It says "this is what a citizen holds", and it stops
 * a reader comparing a payments app to a web page and finding it sparse. A
 * 390-pixel column floating in a white browser looks unfinished; the same
 * column in a phone on a dark desk looks like a product.
 *
 * On an actual phone the conceit is dropped entirely — below 430px the frame
 * becomes the page. A device drawing a picture of a device is a joke that costs
 * screen height on the screen that has least.
 *
 * # What this does NOT replace
 *
 * The operator consoles. A foundation custodian reconciling a seizure, a
 * registrar walking a pedigree, a supervisor reading forty-one executions: none
 * of that belongs in a 390-pixel column, and forcing it there would be the same
 * mistake in the other direction. Those keep .y-folders and .y-data.
 *
 * Pay itself is deliberately untouched and keeps its own copy. It was designed
 * first, the user asked for it to be left alone, and re-pointing a working
 * surface at a new abstraction to save duplication is how a working surface
 * stops working.
 */

/* The desk. Fixed navy in both themes on purpose: a phone photographed on white
   reads as a screenshot of a website rather than as a device. */
.y-stage {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 var(--sp-4) var(--sp-6);
  background: linear-gradient(160deg, #12253f, #0b1523);
}

/* Ink chosen against the desk, never against the page ground, and declared at
   :root rather than inside a media query — a colour defined only under
   prefers-color-scheme is undefined in the un-stamped state most readers are
   actually in. */
:root {
  --desk-ink: #e8eef7;
  --desk-ink-mute: #a9bcd4;
  --stage-w: 1060px;
}

.y-stage__bar {
  width: 100%;
  max-width: var(--stage-w);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-1) var(--sp-5);
  color: var(--desk-ink);
}
.y-stage__bar a { color: inherit; text-decoration: none; }
.y-stage__title {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--desk-ink-mute);
}

.y-phone {
  width: 390px;
  height: 780px;
  max-height: 92vh;
  background: var(--bg);
  border-radius: 38px;
  border: 10px solid #05090f;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.45);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.y-phone__notch {
  position: absolute;
  inset-inline-start: 50%;
  transform: translateX(-50%);
  top: 0;
  width: 140px;
  height: 24px;
  background: #05090f;
  border-end-start-radius: 14px;
  border-end-end-radius: 14px;
  z-index: 5;
}
.y-phone__screen {
  flex: 1;
  display: flex;
  flex-direction: column;
  color: var(--text);
  overflow: hidden;
}

@media (max-width: 430px) {
  /* Below the frame's own width there is no room for a conceit. */
  .y-stage { padding: 0; }
  .y-stage__bar { display: none; }
  .y-phone {
    width: 100%;
    max-height: none;
    height: 100vh;
    height: 100dvh;
    border: 0;
    border-radius: 0;
  }
  .y-phone__notch { display: none; }
}

/* --- the bar at the top of the screen --- */

.y-appbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  /* The top padding clears the notch. */
  padding: 2.2rem var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--rule);
  background: var(--surface);
}
.y-appbar__mark { flex: 0 0 auto; margin-inline-end: var(--sp-2); }
.y-appbar__eyebrow {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.y-appbar__name { font-weight: 600; }
.y-appbar__right {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-inline-start: auto;
}

/* --- one screen, one job --- */

.y-screen {
  flex: 1;
  overflow-y: auto;
  padding: var(--sp-4) var(--sp-4) var(--sp-5);
}
.y-screen__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  letter-spacing: -0.01em;
  margin: var(--sp-1) 0 var(--sp-4);
  text-wrap: balance;
}
.y-screen__sub {
  font-size: var(--step-1);
  font-family: var(--font-display);
  margin: var(--sp-5) 0 var(--sp-1);
}
.y-screen__lede {
  color: var(--text-muted);
  margin: calc(var(--sp-4) * -1) 0 var(--sp-4);
}

/* --- the bar at the bottom --- */

.y-tabbar {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  border-top: 1px solid var(--rule);
  background: var(--surface);
  padding-bottom: var(--sp-2);
}
.y-tab {
  font: inherit;
  font-size: var(--step--1);
  background: none;
  border: 0;
  color: var(--text-muted);
  padding: var(--sp-2) var(--sp-1);
  cursor: pointer;
  display: grid;
  justify-items: center;
  gap: 0.18rem;
  text-decoration: none;
}
.y-tab__icon { width: 20px; height: 20px; }
/* The label shrinks on a 390px screen and must not vanish. An unlabelled glyph
   is a guess, and a wrong guess on these surfaces spends money. */
.y-tab__label { font-size: 0.62rem; line-height: 1.1; }
.y-tab--on { color: var(--accent); box-shadow: inset 0 2px 0 var(--brass); }

/* --- a card, which is what a table becomes on a phone --- */

.y-cards { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-2); }
.y-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 14px;
  box-shadow: var(--shadow-1);
  padding: var(--sp-4);
}
/* A brass edge marks the row that is about money, which is the one a reader is
   looking for. */
.y-card--money { border-inline-start: 3px solid var(--brass); }
.y-card--danger { border-color: var(--bad); }
.y-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
}
.y-card__amount {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--step-2);
  font-weight: 500;
  /* A number never breaks across two lines. See the note on .y-kpi__value. */
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: normal;
}
.y-card__note { color: var(--text-muted); font-size: var(--step--1); margin: var(--sp-1) 0 0; }

/* A row that leads somewhere, which on a phone is most rows. */
.y-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  text-align: start;
  font: inherit;
  color: inherit;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: 14px;
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  text-decoration: none;
}
.y-row:hover { background: var(--surface-2); }
.y-row__main { flex: 1; min-inline-size: 0; }
.y-row__title { font-weight: 600; }
.y-row__sub { color: var(--text-muted); font-size: var(--step--1); }
.y-row__end { text-align: end; flex: 0 0 auto; }
.y-row__chev { color: var(--text-faint); flex: 0 0 auto; }
