/* kg-components.css -- the Kurdography "Bazaar Ledger" component sheet (UI rebuild, Phase 0).
 *
 * Phase 0 part: what home, auth and the legal pages use: app bar, ticker tape, toast, sheet,
 * note, ghost pill, empty state, table.pt, field and page wrapper. Phase 1 appends "legacy
 * primitives (Phase 1)" (the loaders' `.card`, `.stat-tile`, `.pill`, ... under `.panel`) and
 * "shell components (Phase 1)" (bottom bar, avatar-sheet rows, #toast strip, admin entry).
 *
 * Linked AFTER theme.css, components.css, kg-tokens.css and kg-base.css. Where a legacy rule
 * already styles a name restyled here, the rule below uses the same selector form or a more
 * specific one, and a "beats" comment names the legacy line it outranks. Rules of the sheet are
 * those of kg-base.css: logical properties only, no box-shadow, radii limited to
 * 0 / 3px / 4px / 999px / 50%, every colour and font read from kg-tokens.css.
 */

/* ---------- app bar ---------- */

.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-block-size: 52px;
}
.top .kg-title {
  margin: 0;
  font-family: var(--f-display);
  font-size: var(--fs-title);
  font-weight: 700;
  line-height: 1.3;
}
.top .kg-end { display: flex; align-items: center; gap: 14px; color: var(--ink); }
.top .kg-end .ico { inline-size: 22px; block-size: 22px; }

@media (min-width: 1240px) {
  .top { block-size: var(--topbar-h); }
}

/* ---------- ticker: .tape on the phone, .dtick the desktop variant ---------- */

/* One ruled 32px row, always LTR (the latest value sits at the right). Four figures at 360px
   scroll inside the tape: it is a block that scrolls itself, so it never widens the document. */
.dtick, .tape {
  display: flex;
  align-items: center;
  gap: 14px;
  block-size: 32px;
  min-inline-size: 0;
  border-block-start: 1px solid var(--ink);
  border-block-end: 1px solid var(--hair);
  color: var(--ink);
  direction: ltr;
  font-size: 12.5px;
  white-space: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.dtick::-webkit-scrollbar, .tape::-webkit-scrollbar { display: none; }
.dtick { inline-size: 100%; gap: 22px; padding-inline: 24px; border-block-start: 0; }

/* The kilim mark is the DIRECT CHILD <i class="k">. Every .tick carries a span.k label (home.js
   tickItem()), so the mark must never be selected by a descendant .k rule. */
.dtick > i.k, .tape > i.k {
  inline-size: 18px;
  block-size: 7px;
  background: var(--kilim);
  background-size: 14px 7px;
  flex: none;
}

.dtick .tick, .tape .tick { display: inline-flex; align-items: baseline; gap: 5px; flex: none; }
.dtick .tick .k, .tape .tick .k { font-family: var(--f-num); font-size: 11px; font-weight: 700; color: var(--ink-2); } /* beats theme-zella.css l.1003 */
.dtick .tick .v, .tape .tick .v { font-family: var(--f-num); font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); } /* beats theme-zella.css l.1008 */
.dtick .tick .u, .tape .tick .u { font-size: 11px; font-weight: 600; color: var(--ink-3); }

.dtick .ticker-state, .tape .ticker-state { display: inline-flex; align-items: center; gap: 6px; flex: none; color: var(--ink-3); }
.dtick .ticker-state .ticker-dot, .tape .ticker-state .ticker-dot { inline-size: 8px; block-size: 8px; border-radius: 50%; background: var(--ink-3); flex: none; }
.dtick .ticker-state.is-down .ticker-dot, .tape .ticker-state.is-down .ticker-dot { background: var(--loss); }

/* ---------- toast: a 44px strip from the top, 1.5px ink ring ---------- */

.kg-toast {
  position: fixed;
  inset-block-start: 12px;
  inset-inline: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  min-block-size: 44px;
  max-inline-size: 480px;
  margin-inline: auto;
  padding-block: 8px;
  padding-inline: 12px;
  background: var(--paper-2);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 0;
  font-size: var(--fs-small);
  z-index: var(--z-sheet);
  transform: translateY(calc(-100% - 16px));
  transition: transform var(--t-base) var(--ease);
  pointer-events: none;
}
.kg-toast.is-open { transform: none; pointer-events: auto; }

/* ---------- sheet: a bottom sheet on the phone, a side panel from the end edge at 900px ---------- */

/* Closed = translated off-screen and visibility: hidden once the slide has finished, so a closed
   sheet is out of the tab order. Opening switches visibility at once (transition-delay: 0s). */
.kg-sheet {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  max-block-size: 90vh;
  padding-block-start: 16px;
  padding-inline: 20px;
  overflow-y: auto;
  background: var(--paper);
  color: var(--ink);
  border-block-start: 1.5px solid var(--ink);
  border-radius: 0;
  z-index: var(--z-sheet);
  padding-block-end: max(var(--safe-area-inset-bottom, 0px), env(safe-area-inset-bottom));
  transform: translateY(100%);
  visibility: hidden;
  transition: transform var(--t-base) var(--ease), visibility 0s linear var(--t-base);
}
.kg-sheet.is-open { transform: none; visibility: visible; transition-delay: 0s; }

@media (min-width: 900px) {
  .kg-sheet {
    inset-inline-start: auto;
    inset-block: 0;
    inline-size: min(440px, 100%);
    max-block-size: none;
    border-block-start: 0;
    border-inline-start: 1.5px solid var(--ink);
    transform: translateX(100%);
  }
  html[dir="rtl"] .kg-sheet { transform: translateX(-100%); }
  /* html[dir="rtl"] .kg-sheet is more specific than .kg-sheet.is-open: restate the open state */
  html[dir="rtl"] .kg-sheet.is-open { transform: none; }
}

/* ---------- note: a paper-2 slip with a start-side rail; the words carry the meaning ---------- */

.note {
  padding: 12px;
  background: var(--paper-2);
  color: var(--ink);
  border-inline-start: 4px solid var(--ink-3);
  border-radius: 0;
  font-size: 12.5px;
  line-height: 1.6;
}
.note.is-error { background: var(--loss-soft); border-inline-start-color: var(--loss); }
.note.is-ok { background: var(--profit-soft); border-inline-start-color: var(--profit); }
.note.is-warn { background: var(--saffron-soft); border-inline-start-color: var(--saffron); }

/* ---------- ghost pill: the 44px outline pill (delete-account's languages, home's statement button) ---------- */

/* The kg-base .pill (32px, saffron) as an outline with a 44px target; the chosen one is the
   saffron pill. delete-account.js marks it with aria-pressed, a script may use .is-on. */
.pill.ghost {
  min-block-size: 44px;
  min-inline-size: 44px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hair-2);
}
.pill.ghost[aria-pressed="true"],
.pill.ghost.is-on { background: var(--saffron); color: var(--on-saffron); border-color: var(--ink); }

/* ---------- empty state: a ruled section, a seal with one 24px icon, a 3-line message, one .btn ---------- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-block: 24px;
  padding-inline: 20px;
  border-block-start: 1.5px solid var(--ink);
  border-radius: 0;
  color: var(--ink-2);
  line-height: 1.6;
  text-align: center;
} /* beats theme.css l.1507 and its 720px override l.1703 (same selector, later); border-radius: 0 beats theme-appearance.css l.1031 */
.empty-state h2 { margin: 0; font-size: var(--fs-section); font-weight: 700; color: var(--ink); } /* beats theme.css l.1516 */
.empty-state .seal { inline-size: 36px; block-size: 36px; }
.empty-state .seal .ico { inline-size: 24px; block-size: 24px; }
.empty-state.is-error .note { inline-size: 100%; max-inline-size: 44ch; background: var(--loss-soft); border-inline-start-color: var(--loss); text-align: start; }

/* ---------- table.pt: the ledger table (sticky header, numbers to the end, 44px rows) ---------- */

/* The element-only rules table / thead th / tbody td (theme.css l.730-766) are outranked by the
   table.pt prefix. The last-row rule repeats theme.css l.760 so the final row stays open once
   theme.css retires. */
table.pt { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-small); }
table.pt :is(th, td) { padding-block: 8px; padding-inline: 8px; white-space: nowrap; }
table.pt thead th {
  position: sticky;
  inset-block-start: 0;
  background: var(--paper);
  color: var(--ink-3);
  font-size: var(--fs-caption);
  font-weight: 600;
  text-align: start;
  border-block-end: 1px solid var(--hair-2);
}
table.pt tbody tr { block-size: 44px; }
table.pt td { color: var(--ink); border-block-end: 1px solid var(--hair); }
table.pt tbody tr:last-child td { border-block-end: 0; }
/* .num is display: inline-block in kg-base.css, which would pull a cell out of the table: restore
   table-cell. The cell keeps .num's direction: ltr on purpose, so a signed figure is never
   mirrored (+1.05 stays +1.05 in an RTL page); text-align: end then keeps decimals aligned. */
table.pt :is(th, td).num { display: table-cell; text-align: end; }

/* ---------- field: label 13/700, helper under the control ---------- */

.kg-field { display: flex; flex-direction: column; }
.kg-field > label, .kg-field > .kg-label { margin-block-end: var(--label-gap); font-size: var(--fs-small); font-weight: 700; color: var(--ink); }
.kg-field > .kg-helper { margin-block-start: var(--helper-gap); font-size: var(--fs-caption); line-height: 1.5; color: var(--ink-3); }

/* ---------- page wrapper ---------- */

.kg-page { max-inline-size: var(--content-max); margin-inline: auto; padding-inline: 20px; }

@media (min-width: 900px) {
  .kg-page { padding-inline: 24px; }
}

/* ==== legacy primitives (Phase 1) ==== */

/* The classes the dashboard loaders already emit, in the ledger vocabulary (spec section 4.1,
 * DESIGN-SYSTEM.md 3.3 and 4): .card is a ruled section, .card-head the section rule, .stat-tile
 * a kv cell, .pill the flat stamp, .btn-primary the .btn, .notice-* the .note fills, .skeleton-*
 * paper-3 bars. The 41 panel bodies are not edited in Phase 1; these rules are their new look.
 *
 * Cascade. theme.css and components.css are unlayered and load first: every rule here is
 * written under .panel, so it beats a legacy rule on the same subject by specificity (0,2,0
 * against 0,1,0) or, where they tie, by order. kg-compat.css loads AFTER this sheet: its bare
 * copies (.card, .stat-tile, 0,1,0) lose on specificity; where it carries an unscoped copy at
 * 0,2,0 or more (button hover states, .actions > button.btn-primary, the dark .btn-danger,
 * .card.dense, .subtab.is-active) the rule here is raised one step above it and its comment
 * says so (test/kg-primitives.js keeps that table). Panel-scoped copies (#panel-community .card,
 * 1,1,0) are that panel's own look and win on purpose.
 *
 * Not restyled: .tn-*, .countdown*, .row-you (protected surfaces, tokens only until Phase 5).
 * The two tournament status frames .card.tn-dq / .card.tn-exited, which .panel .card would
 * reset, are restated with their legacy values (frame and padding: the same pixels), and so is
 * the countdown's size above 640px, which the --fs-figure token would raise from 32px to 46px. No
 * !important here: the legacy !important lines are inventoried in
 * docs/superpowers/specs/ui-rebuild/TOKENS.md. This section, up to the end marker, is left out
 * of the kg-compat KG_OWNED table (tools/kg-compat/rewrites.js KG_OWNED_SKIP / _END): the names
 * it styles stay legacy names, not kg primitives (ruling R11).
 *
 * Retirement. These rules hit every element of every .panel that carries the name, whichever
 * panel it is in. They are deleted per CLASS, not per panel: a rule goes when no loader emits its
 * name any more (the phase that rebuilds the last panel using it deletes it). Until then the
 * legacy names keep their legacy meaning inside a .panel: a rebuilt panel must not use pill,
 * field or muted with their kg-base.css meaning (the saffron action pill, the kg field, a muted
 * caption) inside a .panel, because the rules below restyle them; it uses the kg names
 * (.stamp.flat, .kg-field, .cap) instead.
 */

/* ---------- card: a ruled section ---------- */

/* beats theme.css l.360 .card and its 720px padding l.1033 (0,1,0), kg-compat.css .card (0,1,0) */
.panel .card {
  background: var(--paper);
  border: 0;
  border-block-start: 1.5px solid var(--ink);
  border-radius: 0;
  box-shadow: none;
  padding-block: 16px;
  padding-inline: 0;
}
/* beats components.css l.5115-5116 #panel-analytics .card and #panel-analytics .kpi-card (1,1,0: border-radius 16px),
   the one panel-scoped copy that meets the rule above (and .panel .kpi-card below) on its corners: kept, it drew the
   ruled section, and the volume tiles of a populated Analytics, with rounded ends, a bracket (the preview walk) */
.panel#panel-analytics .card,
.panel#panel-analytics .kpi-card { border-radius: 0; }
/* beats theme.css l.367 and kg-compat.css .card.dense (0,2,0, later than this sheet) */
.panel .card.dense { padding-block: 12px; padding-inline: 0; }
/* beats theme.css l.368 and kg-compat.css .card + .card (0,2,0, later): the 16px section gap */
.panel .card + .card { margin-block-start: 16px; }
/* beats .panel .card + .card above (0,3,0) by 0,4,0: the metal cards sit side by side in a grid (components.css
   l.1811 .metal-grid), where the gap dropped the second card's ink rule 16px under the first's */
.panel .metal-grid > .card + .card { margin-block-start: 0; }
/* beats .panel .card above for a protected status frame: theme.css l.2332 .card.tn-dq restated (0,3,0), with the
   padding of theme.css l.364 the frame sits around (.panel .card sets padding-inline: 0) */
.panel .card.tn-dq { border: 2px solid var(--critical-fill); padding: var(--sp-5); }
/* beats .panel .card above for a protected status frame: theme.css l.360 + l.2339 .card.tn-exited restated (0,3,0),
   padding as theme.css l.364 */
.panel .card.tn-exited { border: 1px dashed var(--border); padding: var(--sp-5); }
@media (max-width: 720px) {
  /* beats the two frames above (0,3,0, later): the 720px padding of theme.css l.1033 .card, restated */
  .panel .card.tn-dq,
  .panel .card.tn-exited { padding: var(--sp-4); }
}
/* beats theme.css l.2275 .countdown-value (0,1,0), which reads --fs-figure (46px, kg-tokens.css l.190): the live
   32px restated (ruling R42); above 640px only, so theme.css l.2371 (22px on phones) still decides there */
@media (min-width: 641px) { .panel .countdown-value { font-size: 32px; } }

/* ---------- card head: the section rule (title 13/700, kilim 36x9, hairline, tools at the end) ---------- */

/* beats theme.css l.373 .card-head (0,1,0) and kg-compat.css .card-head (0,1,0); display: flex,
   l.380 :empty and the order of the children (l.384-399) stay theme.css's */
.panel .card-head { gap: 10px; margin-block: 0 12px; }
/* beats theme.css l.381 .card-head > h2/h3 and kg-compat.css .card-head>h2/h3 (0,1,1): the .rule b label */
.panel .card-head > :is(h2, h3),
.panel .card-head-copy > :is(h2, h3) {
  margin: 0;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  font-stretch: 100%;
  line-height: 1.4;
  letter-spacing: 0;
}
/* beats nothing (new): the kilim mark after the title, DESIGN-SYSTEM.md section 2 placement 1 */
.panel .card-head > :is(h2, h3)::after,
.panel .card-head-copy > :is(h2, h3)::after {
  content: "";
  display: inline-block;
  inline-size: 36px;
  block-size: 9px;
  margin-inline-start: 10px;
  vertical-align: middle;
  background: var(--kilim);
  background-size: 18px 9px;
}
/* beats nothing (new): the hairline; order 1 puts it after the title and before the tools (order 2). At the head's
   start, 9px down: half the title's 13px / 1.4 line, so it meets the title. Centred on the head it floated beside the
   description of a head that has one under its title (.card-head-copy) */
.panel .card-head::after {
  content: "";
  order: 1;
  align-self: flex-start;
  margin-block-start: 9px;
  flex: 1 1 24px;
  min-inline-size: 24px;
  block-size: 1px;
  background: var(--hair);
}
/* beats theme.css l.391 .card-head .spacer (0,2,0): the hairline takes the free space instead */
.panel .card-head > .spacer { display: none; }

/* beats theme.css l.2348 .card-actions (0,1,0): a ruled action row */
.panel .card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-block-start: 16px;
  padding-block-start: 12px;
  border-block-start: 1px solid var(--hair);
}

/* ---------- page header and section title ---------- */

/* beats components.css l.328 .page-header (0,1,0) and kg-compat.css .page-header (0,1,0); the
   flex layout and its 720px column (components.css l.364) stay */
.panel .page-header {
  gap: 12px;
  padding-block-end: 12px;
  margin-block-end: 16px;
  border-block-end: 1px solid var(--hair);
}
/* beats components.css l.341 and kg-compat.css .page-header h1, .page-header h2 (0,1,1): the title step, Rudaw 26 */
.panel .page-header :is(h1, h2) {
  margin: 0;
  color: var(--ink);
  font-family: var(--f-display);
  font-size: var(--fs-title);
  font-weight: 700;
  font-stretch: 100%;
  line-height: 1.3;
  letter-spacing: 0;
}
/* beats theme.css l.2352 .section-title (0,1,0): the .rule b label over a hairline */
.panel .section-title {
  margin-block: 16px 8px;
  padding-block-end: 4px;
  color: var(--ink-2);
  font-size: 13px;
  font-weight: 700;
  font-stretch: 100%;
  letter-spacing: 0;
  border-block-end: 1px solid var(--hair);
}

/* ---------- stat grid: the 2x2 kv (four to a row on the desktop) ---------- */

/* beats theme.css l.1521 .stat-grid, l.1525 .stat-grid-tight and the 720px l.1697 (0,1,0) */
.panel .stat-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  margin-block: 8px 12px;
  border-block-start: 1px solid var(--hair);
}
/* beats theme.css l.1526 .stat-tile and l.1698 (0,1,0), components.css l.1610, kg-compat.css .stat-tile (0,1,0): a kv cell */
.panel .stat-tile {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
  padding-block: 8px;
  padding-inline: 0 8px;
  background: transparent;
  border: 0;
  border-block-end: 1px solid var(--hair);
  border-radius: 0;
  box-shadow: none;
}
/* beats .panel .stat-tile above (0,4,0): in the kv the second cell of a row carries the start rule */
.panel .stat-grid > .stat-tile:nth-child(even) { border-inline-start: 1px solid var(--hair); padding-inline-start: 12px; }
@media (min-width: 900px) {
  /* beats .panel .stat-grid above (same selector, later): four cells to a row */
  .panel .stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* beats .panel .stat-tile above (0,4,0): the third cell of a four-cell row carries the start rule too */
  .panel .stat-grid > .stat-tile:nth-child(odd) { border-inline-start: 1px solid var(--hair); padding-inline-start: 12px; }
  /* beats the rule above (0,4,0, later): every fourth cell starts a row, without a rule */
  .panel .stat-grid > .stat-tile:nth-child(4n+1) { border-inline-start: 0; padding-inline-start: 0; }
}
/* beats theme.css l.1533 .stat-label (0,1,0) and kg-compat.css .stat-label (0,1,0): the .cap caption; matches
   theme.css l.1539 html[dir="rtl"] .stat-label (0,2,1, font-stretch: 100%, same value) */
.panel .stat-label {
  color: var(--ink-3);
  font-size: 12px;
  font-weight: 500;
  font-stretch: 100%;
  line-height: 1.5;
  letter-spacing: 0;
  text-transform: none;
}
/* beats theme.css l.1540, l.1699 and l.2901 .stat-tile .stat-value (0,2,0, earlier: 8ch, end-aligned) and
   kg-compat.css .stat-value (0,1,0): money-m under its caption at the start side, as the mockup's kv; no colour,
   so the .up/.down rules (components.css l.567-569, kg-compat.css) keep the sign colour */
.panel .stat-value {
  align-self: flex-start;
  min-inline-size: 0;
  font-family: var(--f-num);
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  letter-spacing: 0;
}
/* beats theme.css l.1541 .stat-tile .stat-value.small (0,3,0, earlier) and the pair .panel .stat-value /
   .panel .small (0,2,0 each): the small figure is 13px, stated rather than left to order */
.panel .stat-value.small { font-size: var(--fs-small); }

/* ---------- KPI and tile figures: ruled cells, no box ---------- */

/* beats theme.css l.951 .kpi, .kpi-card and l.989 .kpi-primary (0,2,0, earlier), components.css l.515
   .tile and l.534 .tile:hover (0,2,0, earlier), kg-compat.css .kpi/.kpi-card/.tile (0,1,0) */
.panel .kpi,
.panel .kpi-card,
.panel .tile {
  background: transparent;
  border: 0;
  border-block-start: 1px solid var(--hair);
  border-radius: 0;
  box-shadow: none;
  padding-block: 10px 4px;
  padding-inline: 0;
  transform: none;
}
/* beats components.css l.525 .tile::after (0,1,1): no gradient hover line */
.panel .tile::after { content: none; }
/* beats kg-compat.css :root[data-theme="dark"] .kpi-primary (0,3,0: a navy gradient) and .kpi-primary (0,1,0):
   the lead figure keeps no fill; its size (theme.css l.995 .kpi-primary .kpi-value) marks it */
:root[data-theme] .panel .kpi-primary { background: transparent; }

/* ---------- pill: the flat stamp (24px, 1px current-colour ring); the tone is the colour ---------- */

/* beats theme.css l.656 .badge, .pill (0,1,0), kg-base.css .pill (0,1,0: the 32px saffron action pill)
   and every legacy tone's background and border-color (0,2,0, earlier) */
.panel .pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-block-size: 24px;
  padding-block: 0;
  padding-inline: 8px;
  background: transparent;
  color: var(--ink-2);
  border: 1px solid currentColor;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  font-stretch: 100%;
  line-height: 1.2;
  letter-spacing: 0;
  white-space: nowrap;
}
/* beats components.css l.2274 .pill.ok (0,2,0): profit */
.panel .pill.ok { color: var(--profit); }
/* beats components.css l.2277 .pill.info (0,2,0): ink */
.panel .pill.info { color: var(--ink); }
/* beats components.css l.2275 .pill.warn (0,2,0): saffron-text, as the waiting stamp */
.panel .pill.warn { color: var(--saffron-text); }
/* beats theme.css l.2252 .pill.mid (0,2,0): the grade between warn and bad, saffron-text on a saffron-soft fill */
.panel .pill.mid { color: var(--saffron-text); background: var(--saffron-soft); }
/* beats components.css l.2276 .pill.bad (0,2,0): loss; kg-compat.css :root:not([data-theme="dark"]) .pill.bad
   (0,4,0, colour only, a red of the same family) still wins in the light theme until Phase 5 */
.panel .pill.bad { color: var(--loss); }
/* beats theme.css l.1440 .pill.neutral (0,2,0): ink-2 on paper-2, as .chip.cur */
.panel .pill.neutral { color: var(--ink-2); background: var(--paper-2); }
/* beats theme.css l.1444 .pill.buy (0,2,0): BUY is profit (DESIGN-SYSTEM.md 3.1) */
.panel .pill.buy { color: var(--profit); }
/* beats theme.css l.1445 .pill.sell (0,2,0): SELL is loss */
.panel .pill.sell { color: var(--loss); }
/* beats theme.css l.341 .muted (0,1,0) and .panel .muted below (0,2,0): the unknown grade, a quiet ring */
.panel .pill.muted { color: var(--ink-2); border-color: var(--hair-2); }

/* ---------- notice: the .note fills (start-side rail, the words carry the meaning) ---------- */

/* beats components.css l.1698 .notice (0,1,0) and kg-compat.css .notice (0,1,0). display is not set:
   components.css l.1722 .notice[hidden] (!important) keeps hiding it. keep in sync with .note (l.147) */
.panel .notice {
  padding: 12px;
  background: var(--paper-2);
  color: var(--ink);
  border: 0;
  border-inline-start: 4px solid var(--ink-3);
  border-radius: 0;
  box-shadow: none;
  font-size: 12.5px;
  line-height: 1.6;
}
/* beats components.css l.1709 .notice::before (0,1,1): no radial wash */
.panel .notice::before { content: none; }
/* beats components.css l.1716 .notice-info (0,1,0) and .panel .notice above (0,2,0): the tone names both classes,
   so it wins by specificity, not by order (the loaders always write notice notice-<tone>) */
.panel .notice.notice-info { background: var(--paper-2); border-inline-start-color: var(--ink); }
/* beats components.css l.1717 .notice-warn (0,1,0) and .panel .notice; .notice-warning (tournament.js l.195) has no legacy rule */
.panel .notice.notice-warn,
.panel .notice.notice-warning { background: var(--saffron-soft); border-inline-start-color: var(--saffron); }
/* beats components.css l.1718 .notice-error (0,1,0) and .panel .notice */
.panel .notice.notice-error { background: var(--loss-soft); border-inline-start-color: var(--loss); }
/* beats components.css l.1719 .notice-ok (0,1,0) and .panel .notice */
.panel .notice.notice-ok { background: var(--profit-soft); border-inline-start-color: var(--profit); }
/* beats the pair .panel .notice / .panel .small (0,2,0 each, the second later): a small notice keeps the note size */
.panel .notice.small { font-size: 12.5px; }
/* beats kg-components.css .panel .notice.notice-error (0,3,0) and .panel .notice (0,2,0) above, and .panel .empty-state
   below (0,2,0): errorState() roots are `empty-state is-error notice notice-error` (ruling R25); the error state is the
   ruled section, its .note.is-error slip carries the fill (not a box in a box) */
.panel .empty-state.is-error.notice { background: transparent; border: 0; border-block-start: 1.5px solid var(--ink); padding: 16px 0; color: var(--ink); }

/* ---------- field and check ---------- */

/* beats components.css l.856 .field (0,1,0) and kg-base.css .field (0,1,0) */
.panel .field { display: flex; flex-direction: column; gap: var(--label-gap); min-inline-size: 0; }
/* beats components.css l.857 .field label (0,1,1): the .kg-field label, 13/700 ink */
.panel .field > label:not(.check) { color: var(--ink); font-size: var(--fs-small); font-weight: 700; }
/* beats components.css l.858 .field .hint (0,2,0, earlier) and kg-compat.css .hint (0,1,0): the helper caption */
.panel .field .hint { color: var(--ink-3); font-size: var(--fs-caption); font-weight: 500; }
/* beats theme.css l.640 .check (0,1,0): a 44px tappable row; display and align-items stay theme.css's */
.panel .check { gap: 10px; min-block-size: 44px; color: var(--ink); font-size: var(--fs-small); cursor: pointer; }

/* ---------- buttons: .btn-primary is the .btn, .btn-sm the 38px ghost, .btn-danger the .btn in loss ---------- */

/* beats components.css l.1659 + l.1682 .btn-primary (0,1,0), theme.css l.1710 (720px min-height) and
   kg-compat.css .btn-primary (0,1,0); the .actions twin (0,3,0) beats kg-compat.css .actions>button.btn-primary (0,2,1) */
.panel .btn-primary,
.panel .actions > .btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-block-size: 48px;
  padding-block: 0;
  padding-inline: 16px;
  background: var(--saffron);
  color: var(--on-saffron);
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  box-shadow: none;
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: 0;
}
/* beats kg-compat.css .btn-primary::after (0,1,1, the motion.css sheen) and its hover/RTL variants, which then
   have no box. No ::before rule: the loaders write a bare btn-primary, and btn btn-primary is kg-base.css l.247 */
.panel .btn-primary::after { content: none; }
/* beats components.css l.1683 and kg-compat.css .btn-primary:hover:not(:disabled) (0,3,0) and the .actions twin (0,4,1) */
.panel .btn-primary:hover:not(:disabled),
.panel .actions > .btn-primary:hover:not(:disabled) {
  background: var(--saffron);
  border-color: var(--ink);
  box-shadow: none;
  transform: none;
  filter: brightness(.95);
}
/* beats kg-compat.css .btn-primary:active:not(:disabled) (0,3,0) and the .actions twin (0,4,1) */
.panel .btn-primary:active:not(:disabled),
.panel .actions > .btn-primary:active:not(:disabled) { box-shadow: none; transform: none; filter: brightness(.9); }

/* beats components.css l.1658 .btn-sm (0,1,0), theme.css l.1709 (720px) and kg-compat.css .btn-sm (0,1,0): .btn.ghost
   at 38px; the toolbar rules .card-head-tools button.btn-sm (components.css l.1689, 0,2,1) keep their 44px height */
.panel .btn-sm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-block-size: var(--control-h-sm);
  padding-block: 0;
  padding-inline: 12px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--hair-2);
  border-radius: 4px;
  box-shadow: none;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0;
}
/* beats components.css l.1672 .btn-sm:hover:not(:disabled) (0,3,0): the ghost's hover, paper-2 under an ink-3 ring */
.panel .btn-sm:hover:not(:disabled) { background: var(--paper-2); border-color: var(--ink-3); }
/* beats .panel .btn-sm and .panel .btn-primary above (0,2,0 each: order alone would make it a ghost) and
   kg-compat.css .actions>button.btn-primary (0,2,1): the small primary is the .btn at 38px */
.panel .btn-sm.btn-primary {
  min-block-size: var(--control-h-sm);
  padding-inline: 12px;
  background: var(--saffron);
  color: var(--on-saffron);
  border: 1.5px solid var(--ink);
  font-size: var(--fs-small);
}
/* beats .panel .btn-sm:hover above and .panel .btn-primary:hover (0,4,0 each), kg-compat.css hover twins (0,4,1) */
.panel .btn-sm.btn-primary:hover:not(:disabled) { background: var(--saffron); border-color: var(--ink); filter: brightness(.95); }

/* beats components.css l.1660 + l.1684 and theme.css l.2418 .btn-danger (0,1,0); the :root[data-theme] twin (0,4,0)
   beats kg-compat.css :root[data-theme="dark"|"system"] .btn-danger (0,3,0): the .btn in loss */
.panel .btn-danger,
:root[data-theme] .panel .btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-block-size: 48px;
  padding-block: 0;
  padding-inline: 16px;
  background: var(--loss);
  color: var(--paper);
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  box-shadow: none;
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: 0;
}
/* beats theme.css l.2424 and components.css l.1685 .btn-danger:hover:not(:disabled) (0,3,0); the .actions twin (0,5,0)
   beats l.1685's second selector .actions > button.btn-danger:hover:not(:disabled) (0,4,1: #lockNowBtn) */
.panel .btn-danger:hover:not(:disabled),
.panel .actions > .btn-danger:hover:not(:disabled) { background: var(--loss); border-color: var(--ink); color: var(--paper); filter: brightness(.95); }
/* beats theme.css l.2419 .btn-sm.btn-danger (0,2,0) and the .btn-danger rules above (0,2,0 / 0,4,0 with the
   :root[data-theme] twin at 0,5,0): the small destructive button is a ghost in loss */
.panel .btn-sm.btn-danger,
:root[data-theme] .panel .btn-sm.btn-danger {
  min-block-size: var(--control-h-sm);
  padding-inline: 12px;
  background: transparent;
  color: var(--loss);
  border: 1px solid var(--loss);
  font-size: var(--fs-small);
}
/* beats theme.css l.2425 .btn-sm.btn-danger:hover:not(:disabled) (0,4,0) and the twin above (0,5,0, earlier) */
.panel .btn-sm.btn-danger:hover:not(:disabled),
:root[data-theme] .panel .btn-sm.btn-danger:hover:not(:disabled) { background: var(--loss); border-color: var(--loss); color: var(--paper); }
@media (max-width: 720px) {
  /* beats theme.css l.1709 (720px: .btn-sm { min-height: var(--control-h-lg) }, 0,1,0), which the four 38px rules
     above outrank (same selectors, earlier): on a phone a small button is a 44px touch target (DESIGN-SYSTEM.md 7) */
  .panel .btn-sm,
  .panel .btn-sm.btn-primary,
  .panel .btn-sm.btn-danger,
  :root[data-theme] .panel .btn-sm.btn-danger { min-block-size: 44px; }
}
/* beats theme.css l.507 .btn.danger (0,2,0: white on --critical-fill, which is --loss: #E0665E in the ink theme,
   3.4:1) and l.512 .btn.danger:hover:not(:disabled) (0,4,0) by 0,3,0 / 0,5,0: the .btn in loss, paper words */
.panel .btn.danger,
.panel .btn.danger:hover:not(:disabled) { background: var(--loss); color: var(--paper); border-color: var(--ink); }
/* beats nothing at 0,3,0 (components.css l.1675 dims .btn-sm only): the 48px buttons get the same disabled state */
.panel .btn-primary:disabled,
.panel .btn-danger:disabled { opacity: .45; cursor: not-allowed; filter: none; }

/* beats theme.css l.2457 .link-button (0,1,0: colour var(--primary), which is saffron as text) and l.1713 (720px):
   the text link, saffron-text with a 1.5px saffron underline */
.panel .link-button {
  min-block-size: 44px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--saffron-text);
  font: inherit;
  font-weight: 700;
  text-align: start;
  text-decoration: underline;
  text-decoration-color: var(--saffron);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  cursor: pointer;
}
/* beats theme.css l.2471 .link-button:hover (0,2,0, earlier than the rule above) */
.panel .link-button:hover { color: var(--ink); text-decoration-thickness: 2px; }

/* ---------- saffron is never text: the legacy rules that write --primary / --accent as a colour ---------- */

/* beats components.css l.3460 th.news-col-platform (0,1,1: colour var(--primary), saffron on the saffron-soft
   column, 2.1:1 in the paper theme) by 0,2,1: the head of the News table's platform column in saffron-text */
.panel th.news-col-platform { color: var(--saffron-text); }
/* beats theme.css l.687 .badge.primary (0,2,0) and components.css l.805 .badge-profit_locked (0,1,0), both the
   saffron alias as text on --primary-soft, by 0,3,0: the two saffron badges read in saffron-text. The second class
   is built by app.js l.1347 as `badge badge-${status}`, so no script holds the whole word: named by its status */
.panel .badge.primary,
.panel .badge[class*="profit_locked"] { color: var(--saffron-text); }
/* beats components.css l.2505 .prio-rank (0,1,0: colour var(--accent) on --accent-subtle, saffron on saffron-soft,
   2.1:1 in the paper theme) by 0,2,0: the rank number of the Analytics assessment's "improve first" list */
.panel .prio-rank { color: var(--saffron-text); }
/* beats components.css l.2370 .combo-option mark (0,1,1) by 0,2,1 and l.2372 .combo-custom .q (0,2,0) by 0,3,0:
   the matched letters and the echo of what was typed in the Accounts server list, saffron on paper-3 (1.9:1) */
.panel .combo-option mark,
.panel .combo-custom .q { color: var(--saffron-text); }

/* ---------- muted and small text ---------- */

/* beats theme.css l.341 .muted and kg-compat.css .muted (0,1,0): ink-3, captions of 12px and up */
.panel .muted { color: var(--ink-3); }
/* beats theme.css l.342 .small (0,1,0) */
.panel .small { font-size: var(--fs-small); }

/* ---------- data table: the table.pt ledger ---------- */

/* beats theme.css l.1548 .data-table (0,1,0) and kg-compat.css .data-table (0,1,0: border-collapse: separate) */
.panel .data-table { inline-size: 100%; border-collapse: collapse; border-spacing: 0; font-size: var(--fs-small); }
/* beats theme.css l.1549 .data-table th (0,1,1) and kg-compat.css .data-table thead th (0,1,2) */
.panel .data-table th {
  position: sticky;
  inset-block-start: 0;
  z-index: 1;
  padding-block: 8px;
  padding-inline: 8px;
  background: var(--paper);
  color: var(--ink-3);
  font-size: var(--fs-caption);
  font-weight: 600;
  font-stretch: 100%;
  letter-spacing: 0;
  text-transform: none;
  text-align: start;
  white-space: nowrap;
  border-block-end: 1px solid var(--hair-2);
}
/* beats theme.css l.1563 .data-table td (0,1,1) and kg-compat.css .data-table tbody td (0,1,2) */
.panel .data-table td {
  padding-block: 8px;
  padding-inline: 8px;
  color: var(--ink);
  vertical-align: middle;
  border-block-end: 1px solid var(--hair);
}
/* beats .panel .data-table th above (0,2,1) back to theme.css l.1562 (0,2,1, earlier): figures to the end */
.panel .data-table :is(th, td).num { text-align: end; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* beats .panel .data-table td above (0,2,1): the last row stays open, as theme.css l.1571 */
.panel .data-table tbody tr:last-child td { border-block-end: 0; }
/* beats .panel .data-table td above (0,2,1, later than components.css l.567-569 td.num.up / td.num.down at the same
   weight, so its ink won): a signed figure keeps its sign colour (four tables of Analytics drew their losses in ink) */
.panel .data-table td.up { color: var(--profit); }
.panel .data-table td.down { color: var(--loss); }
/* beats theme.css l.2912 and components.css l.779 .table-scroll, kg-compat.css .table-scroll (0,1,0: radius 12px,
   the 720px border and negative margin) */
.panel .table-scroll { max-inline-size: 100%; overflow-x: auto; margin-inline: 0; border: 0; border-radius: 0; }
@media (max-width: 720px) {
  /* beats theme.css l.2919-2920 .data-table.has-sticky-start th/td:first-child (0,3,1) and the RTL twin l.2927-2928
     (0,4,2, earlier): the sticky first column keeps a hairline, not a shadow */
  .panel .data-table.has-sticky-start tr > :is(th, td):first-child {
    background: var(--paper);
    box-shadow: none;
    border-inline-end: 1px solid var(--hair);
  }
}
@media (max-width: 360px) {
  /* beats components.css l.136 .data-table.is-stack tr (0,2,1): a stacked row is a slip, radius 0 */
  .panel .data-table.is-stack tr { background: var(--paper-2); border: 1px solid var(--hair-2); border-radius: 0; }
  /* beats .panel .data-table td above (0,2,1, later than components.css l.143): the stacked cell stays open */
  .panel .data-table.is-stack td { border: 0; padding-inline: 0; }
  /* beats the 720px sticky first column above (0,4,2): stacked, it is static (components.css l.158) and needs
     neither its paper ground nor its end hairline */
  .panel .data-table.is-stack.has-sticky-start tr > :is(th, td):first-child { background: transparent; border-inline-end: 0; }
}

/* ---------- subtabs: text tabs with the kilim mark under the chosen one ---------- */

/* beats components.css l.2123 .subtabs and kg-compat.css .subtabs (0,1,0: the pill track) */
.panel .subtabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin-block-end: 16px;
  padding: 0;
  overflow-x: auto;
  scrollbar-width: none;
  background: transparent;
  border: 0;
  border-block-end: 1px solid var(--hair);
  border-radius: 0;
  box-shadow: none;
}
/* beats nothing (new): no scrollbar on the tab row, as #showTabs (kg-home.css) */
.panel .subtabs::-webkit-scrollbar { display: none; }
/* beats components.css l.2124 .subtab and kg-compat.css .subtab (0,1,0: radius 999px) */
.panel .subtab {
  position: relative;
  flex: none;
  min-block-size: 44px;
  padding-block: 0;
  padding-inline: 10px;
  background: none;
  color: var(--ink-3);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font-size: var(--fs-small);
  font-weight: 600;
  white-space: nowrap;
  transition: color var(--t-fast) var(--ease);
}
/* beats components.css l.2129 .subtab:hover (0,2,0, earlier than the rule above) */
.panel .subtab:hover { color: var(--ink); }
/* beats kg-base.css :focus-visible (0,1,0, outline-offset 2px): the ring sits inside the tab, where the
   scrolling row (overflow-x: auto) cannot clip it */
.panel .subtab:focus-visible { outline-offset: -2px; }
/* beats components.css l.2130 .subtab.is-active and kg-compat.css .subtab.is-active / .subtab[aria-selected="true"]
   (0,2,0, later than this sheet): ink and bold, no fill, no shadow */
.panel .subtab.is-active,
.panel .subtab[aria-selected="true"] {
  color: var(--ink);
  font-weight: 700;
  background: none;
  box-shadow: none;
}
/* beats nothing (new): the 24x6 kilim mark, DESIGN-SYSTEM.md section 2 placement 2 */
.panel .subtab.is-active::after,
.panel .subtab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: calc(50% - 12px);
  inline-size: 24px;
  block-size: 6px;
  background: var(--kilim);
  background-size: 12px 6px;
}

/* ---------- skeletons: paper-3 bars ---------- */

/* beats theme.css l.1448 .skeleton-block (0,1,0) */
.panel .skeleton-block { display: flex; flex-direction: column; gap: 8px; padding-block: 8px; padding-inline: 0; }
/* beats theme.css l.1449 .skeleton-row and its reduced-motion twin l.1460 (0,1,0): flat, square, a 44px ledger row */
.panel .skeleton-row { block-size: 44px; background: var(--paper-3); border-radius: 0; animation: none; }

/* ---------- empty state: the Phase 0 rule above, at panel specificity ---------- */

/* beats components.css l.1031 .table-empty-cell .empty-state (0,2,0, earlier) and theme.css l.1507 / l.1703.
   keep in sync with .empty-state (l.176) */
.panel .empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-block: 24px;
  padding-inline: 20px;
  border-block-start: 1.5px solid var(--ink);
  border-radius: 0;
  color: var(--ink-2);
  line-height: 1.6;
  text-align: center;
}
/* beats .panel .empty-state above (0,3,0): inside a card (itself a ruled section) the card's top line is the rule */
.panel .card .empty-state { border-block-start: 0; }
/* beats .panel .empty-state.is-error.notice (0,4,0, the R25 error state above) and .panel .card .empty-state (0,3,0): an
   errorState() inside a .card must not draw its own ink rule under the card's top line */
.panel .card .empty-state.is-error.notice { border-block-start: 0; }

/* ---------- empty row: a quiet line of the ledger (td.empty in a table, div.empty in the broker list) ---------- */

/* beats components.css l.781 .empty (0,1,0: a surface fill inside a dashed, rounded box) and kg-compat.css .empty
   (0,1,0: radius 14px, text-muted): no box, the words in ink-2 as .panel .empty-state; its wash is taken off in
   kg-dash.css (.empty::before) */
.panel .empty { background: transparent; border: 0; border-radius: 0; color: var(--ink-2); }

/* ---------- forced colours: hairlines drawn as backgrounds ---------- */

@media (forced-colors: active) {
  /* beats .panel .card-head::after above (a background, forced to Canvas otherwise): the hairline stays visible */
  .panel .card-head::after { background: CanvasText; }
}

/* ==== end legacy primitives (Phase 1) ==== */

/* ==== shell components (Phase 1) ==== */

/* The kg-native pieces of the dashboard shell (spec sections 4.3 and 4.4, DESIGN-SYSTEM.md section 4
 * "Bottom bar", "Sheets", "Toasts"): the phone-web bottom bar .kg-bar, the rows of the avatar sheet
 * (#userMenuPopover.user-popover.kg-sheet), the #toast strip and the rail's admin entry. The layout
 * of the shell (grid, rail, drawer, app bar, sub-rail) is kg-dash.css, which only the dashboard links.
 *
 * Kg-owned. Unlike the legacy primitives section above, the names here are kg names: this section
 * is read into the kg-compat KG_OWNED table (tools/kg-compat/rewrites.js, ruling R11), so its
 * markers keep the form of the legacy section's. Every rule carries a "beats" comment.
 *
 * The bar is markup app.js builds at boot (plan Task 8): nav#kgBar.kg-bar > i.kg-bar-mark +
 * five a.kg-bar-slot[data-slot][data-panel] (svg.ico + span.kg-bar-label); aria-current="page"
 * marks the chosen slot and data-badge carries a count. It is direction: ltr in every language.
 */

/* ---------- bottom bar: five slots, the kilim mark above the chosen one, the phone web only ---------- */

/* beats nothing (new). Hidden above 720px; 84px including the home indicator (DESIGN-SYSTEM.md 3.3);
   kg-dash.css pads the body by the same height while the bar can show */
.kg-bar {
  display: none;
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 84px;
  direction: ltr;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  align-items: stretch;
  background: var(--paper);
  color: var(--ink-2);
  border-block-start: 1.5px solid var(--ink);
  z-index: var(--z-bars);
  padding-block-end: max(var(--safe-area-inset-bottom, 0px), env(safe-area-inset-bottom));
}
@media (max-width: 720px) {
  /* beats .kg-bar above (same selector, later): the website phone shows the bar */
  .kg-bar { display: grid; }
}
/* beats .kg-bar and its 720px twin above (0,2,0 / 0,2,1 against 0,1,0): the app frame, the native
   shell, an open sheet, the keyboard and the learning viewer hide the bar; [hidden] is the guard for a
   script that hides it, since display: grid outranks the user-agent [hidden] rule */
.kg-bar[hidden],
html.tc-app .kg-bar,
html[data-native] .kg-bar,
html.kg-sheet-open .kg-bar,
html.kg-kb-open .kg-bar,
html.lrn-viewing .kg-bar { display: none; }

/* beats theme.css l.275 a (0,0,1: saffron, underlined): a slot is at least 44px each way; the icon sits
   under the kilim mark's lane. ink-2, not ink-3: the label is 11px and ink-3 is for captions of 12px
   and up (DESIGN-SYSTEM.md 3.1) */
.kg-bar-slot {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 4px;
  min-block-size: 44px;
  min-inline-size: 44px;
  padding-block: 18px 4px;
  padding-inline: 2px;
  color: var(--ink-2);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
/* beats theme.css l.283 a:hover (0,1,1): no underline on hover, as a tab */
.kg-bar-slot:hover { color: var(--ink); text-decoration: none; }
/* beats kg-base.css :focus-visible (0,1,0, outline-offset 2px): the ring stays inside the bar */
.kg-bar-slot:focus-visible { outline-offset: -2px; }
/* beats kg-base.css .ico (0,1,0, same size): stated so the bar never depends on it */
.kg-bar-slot .ico { inline-size: 22px; block-size: 22px; flex: none; }
/* beats nothing (new): the 11px label, Archivo for Latin and digits, Vazirmatn for Arabic script;
   plaintext lets each label take its own direction inside the LTR bar */
.kg-bar-label {
  max-inline-size: 100%;
  overflow: hidden;
  font-family: var(--f-num);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
  unicode-bidi: plaintext;
}
/* beats .kg-bar-label above (0,3,0 against 0,1,0): the label clips its overflow for the ellipsis, and its 1.3 line
   box cut what Arabic script hangs below the baseline («ڕیلز» read «ریلز», «گەڕان» «گەران»): 1.6 for Sorani and
   Arabic, 17.6px of the slot's 84; the Latin labels keep 1.3 */
:root:lang(ckb) .kg-bar-label,
:root:lang(ar) .kg-bar-label { line-height: 1.6; }
/* beats .kg-bar-slot above (0,2,0): the chosen slot is ink, its label bold */
.kg-bar-slot[aria-current="page"] { color: var(--ink); }
/* beats .kg-bar-label above (0,3,0) */
.kg-bar-slot[aria-current="page"] .kg-bar-label { font-weight: 700; }
/* beats nothing (new): the badge, a madder dot 18px with an Archivo 11 count, at the icon's top end
   (--on-badge on --badge: 7.0:1 in the paper theme, 5.5:1 in the ink theme) */
.kg-bar-slot[data-badge]::after {
  content: attr(data-badge);
  position: absolute;
  inset-block-start: 10px;
  inset-inline-end: calc(50% - 22px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 18px;
  block-size: 18px;
  padding-inline: 4px;
  background: var(--badge);
  color: var(--on-badge);
  border-radius: 999px;
  font-family: var(--f-num);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
/* beats .kg-bar-slot[data-badge]::after above (0,2,1, same specificity, later): an empty badge draws no dot */
.kg-bar-slot[data-badge=""]::after { content: none; }

/* beats nothing (new): the one shared mark, 24x6 kilim, moved to the chosen slot by motion.js
   (plan Task 11) with transform; the bar is LTR, so inline-start is the left edge */
.kg-bar-mark {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-start: 0;
  inline-size: 24px;
  block-size: 6px;
  background: var(--kilim);
  background-size: 12px 6px;
  pointer-events: none;
  transition: transform var(--t-fast) var(--ease);
}
/* beats nothing (new): until motion.js has put the mark under a slot (it then adds .is-placed) the mark
   rests at the bar's left edge, where it must not be drawn; a bar page with no current slot clears the
   class again, so the mark is hidden there too */
.kg-bar-mark:not(.is-placed) { visibility: hidden; }
@media (prefers-reduced-motion: reduce) {
  /* beats .kg-bar-mark above (same selector, later): the mark jumps */
  .kg-bar-mark { transition: none; }
}

/* ---------- the avatar sheet: #userMenuPopover as a .kg-sheet (rows, language and theme) ---------- */

/* The avatar sheet has ONE switch (ruling R18): `hidden` closes it; `.is-open` is optional and only animates.
   Shown (no [hidden]) it is on screen and slides in once (kg-sheet-in below); [hidden] wins over both
   (theme.css l.233 is !important, and the guard below). */
/* beats components.css l.2099 .user-popover (0,1,0: an absolute dropdown under the avatar, 1px ring,
   shadow, radius, tc-rise animation) where .kg-sheet (0,1,0) above does not restate the property; the
   dropdown's top offset would stretch the phone sheet: inset-block-start: auto */
.user-popover.kg-sheet {
  position: fixed;
  inset-block-start: auto;
  min-inline-size: 0;
  z-index: var(--z-sheet);
  padding-block-start: 8px;
  border: 0;
  border-block-start: 1.5px solid var(--ink);
  border-radius: 0;
  box-shadow: none;
  animation: none;
}
/* beats .user-popover.kg-sheet above (0,3,0): the guard for when theme.css (its [hidden] rule) retires */
.user-popover.kg-sheet[hidden] { display: none; }
/* beats .kg-sheet and .kg-sheet.is-open above (0,1,0 / 0,2,0) and the 900px html[dir="rtl"] .kg-sheet (0,2,1):
   without [hidden] the sheet is open, whatever .is-open says; the slide is an animation, which (unlike a
   transition) runs when display comes back from none */
.user-popover.kg-sheet:not([hidden]) {
  visibility: visible;
  transform: none;
  animation: kg-sheet-in var(--t-base) var(--ease);
}
@keyframes kg-sheet-in { from { transform: translateY(100%); } }
@keyframes kg-sheet-in-end { from { transform: translateX(100%); } }
@keyframes kg-sheet-in-end-rtl { from { transform: translateX(-100%); } }
@media (min-width: 900px) {
  /* beats .user-popover.kg-sheet above (same selector, later): the side panel from the end edge, as the
     900px .kg-sheet rule above, which the 0,2,0 rule would otherwise outrank */
  .user-popover.kg-sheet { inset-block-start: 0; border-block-start: 0; border-inline-start: 1.5px solid var(--ink); }
  /* beats .user-popover.kg-sheet:not([hidden]) above (same selector, later / 0,4,1): the side panel slides in
     from the end edge, the left one in RTL */
  .user-popover.kg-sheet:not([hidden]) { animation-name: kg-sheet-in-end; }
  html[dir="rtl"] .user-popover.kg-sheet:not([hidden]) { animation-name: kg-sheet-in-end-rtl; }
}
@media (prefers-reduced-motion: reduce) {
  /* beats the three animation rules above (same selectors, later): the sheet appears at once */
  .user-popover.kg-sheet:not([hidden]),
  html[dir="rtl"] .user-popover.kg-sheet:not([hidden]) { animation: none; }
}

/* beats components.css l.2107 .user-popover-head (0,1,0) if the head keeps that class: avatar, name, email */
.kg-sheet .kg-sheet-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-block: 8px 12px;
  padding-inline: 4px;
  margin-block-end: 4px;
  border-block-end: 1px solid var(--hair);
}
/* beats components.css l.2109 .user-popover-id strong (0,1,1): the name, 15/700 ink */
.kg-sheet .kg-sheet-head strong { color: var(--ink); font-size: var(--fs-body); font-weight: 700; }

/* beats components.css l.2111 .user-popover-item and l.2119 :hover (0,1,0 / 0,2,0), which #menuSettings and
   #menuLogout keep: a 48px row, a 22px icon at the start, the label in ink */
.kg-sheet .kg-sheet-item {
  display: flex;
  align-items: center;
  gap: 12px;
  inline-size: 100%;
  min-block-size: 48px;
  padding-block: 0;
  padding-inline: 4px;
  background: none;
  color: var(--ink);
  border: 0;
  border-radius: 0;
  font: inherit;
  font-size: var(--fs-body);
  font-weight: 500;
  text-align: start;
  cursor: pointer;
}
/* beats components.css l.2119 .user-popover-item:hover (0,2,0) */
.kg-sheet .kg-sheet-item:hover { background: var(--paper-2); color: var(--ink); }
/* beats kg-base.css :focus-visible (0,1,0): the ring sits inside the row, where the scrolling sheet cannot clip it */
.kg-sheet .kg-sheet-item:focus-visible { outline-offset: -2px; }
/* beats kg-base.css .ico (0,1,0): the row icon, ink-2 */
.kg-sheet .kg-sheet-item .ico { inline-size: 22px; block-size: 22px; flex: none; color: var(--ink-2); }
/* beats nothing (new): a 48px row holding a control (the language select, the theme button and its word) */
.kg-sheet .kg-sheet-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-block-size: 48px;
  padding-inline: 4px;
  color: var(--ink);
  font-size: var(--fs-body);
}
/* beats nothing (new): a 1px hair rule between the groups of rows */
.kg-sheet .kg-sheet-sep { block-size: 1px; margin-block: 8px; background: var(--hair); }

/* ---------- toast: #toast as the .kg-toast strip, with a flat stamp at the start ---------- */

/* beats components.css l.1726 .toast (0,1,0: a bottom-end card, opacity 0, shadow) and its 720px inset
   l.2564, kg-compat.css #toast,.toast (1,0,0: a 4px accent start border) and .toast.err (0,2,0); the
   .kg-toast rule above (0,1,0) carries the rest. inset-block-end: auto, or the bottom offset of
   components.css would stretch the strip down the page. z-index 120, the live toast's (components.css l.1729):
   above the full-screen Community layers that raise toasts themselves (kg-compat.css .ig-follows 96,
   .ig-hl-editor 97), which --z-sheet (95) is under */
#toast.kg-toast {
  inset-block-start: 12px;
  inset-block-end: auto;
  inset-inline: 12px;
  min-block-size: 44px;
  max-inline-size: 480px;
  margin-inline: auto;
  padding-block: 8px;
  padding-inline: 12px;
  background: var(--paper-2);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: 0;
  box-shadow: none;
  opacity: 1;
  z-index: 120;
  transform: translateY(calc(-100% - 16px));
  transition: transform var(--t-base) var(--ease);
  pointer-events: none;
}
/* beats #toast.kg-toast above (1,2,0 against 1,1,0): app.js toast() adds .on to show it (the twin of
   .kg-toast.is-open) */
#toast.kg-toast.on,
#toast.kg-toast.is-open { transform: none; pointer-events: auto; }
/* beats nothing (new): the stamp at the start, as .stamp.flat (24px, 1.5px current-colour ring, 11/700) */
#toast.kg-toast::before {
  content: attr(data-stamp);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-block-size: 24px;
  padding-inline: 8px;
  color: var(--ink);
  border: 1.5px solid currentColor;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
}
/* beats #toast.kg-toast::before above (1,2,1 each against 1,1,1): no stamp word, no ring */
#toast.kg-toast:not([data-stamp])::before,
#toast.kg-toast[data-stamp=""]::before { content: none; }
/* beats #toast.kg-toast::before above (1,2,1 against 1,1,1): an error stamps in loss */
#toast.kg-toast.err::before { color: var(--loss); }

/* ---------- the rail's admin entry «بەڕێوەبردن» (admins only: data-admin-only + hidden) ---------- */

/* beats nothing (new): a 44px entry, a 22px icon over an 11px label; kg-dash.css places it in the rail
   foot and lays it out as a row in the drawer */
.kg-rail-admin {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  inline-size: 100%;
  min-block-size: 44px;
  padding-block: 4px;
  padding-inline: 4px;
  background: none;
  color: var(--ink-2);
  border: 0;
  border-radius: 0;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  cursor: pointer;
}
/* beats .kg-rail-admin above (0,2,0): hidden for everyone but an administrator */
.kg-rail-admin[hidden] { display: none; }
/* beats .kg-rail-admin above (0,2,0) */
.kg-rail-admin:hover { color: var(--ink); }
/* beats kg-base.css :focus-visible (0,1,0): inside the rail, which clips overflow */
.kg-rail-admin:focus-visible { outline-offset: -2px; }
/* beats kg-base.css .ico (0,1,0, same size): stated */
.kg-rail-admin .ico { inline-size: 22px; block-size: 22px; flex: none; }

@media (forced-colors: active) {
  /* beats .kg-sheet .kg-sheet-sep above (a background, forced to Canvas otherwise): the rule stays visible */
  .kg-sheet .kg-sheet-sep { background: CanvasText; }
}

/* ==== end shell components (Phase 1) ==== */

/* ==== Phase 2 contrast decisions (release 2.1) ==== */
/* over kg-base.css l.38 :focus-visible (0,1,0), later sheet: the ring's colour only; width, offset and forced colours stay kg-base's */
:focus-visible { outline-color: var(--focus); }
/* over kg-base.css l.378 (0,1,1), later sheet */
input:focus-visible, select:focus-visible, textarea:focus-visible { outline-color: var(--focus); }
/* ==== end Phase 2 contrast decisions ==== */
