/* =============================================================================
   components.css — the class contract. Screens USE these; they do not restyle
   them. If a screen needs a variant, the variant is added here.

   Contract (P0_CONTRACT.md):
     .btn .btn--primary .btn--ghost .btn--danger .btn--sm .btn--flood
     .chip .chip--ok|info|warn|bad|neutral
     .badge .badge--ok|info|warn|bad|neutral
     .card .card__head .card__title .card__body .card__foot
     .metric .metric__num .metric__unit .metric__label
     .meter .meter__fill
     .field .field__label .field__input .field__hint .field__err
     .table .table--dense
     .tabs .tabs__tab[aria-selected]
     .rail .rail__item .rail__item--active
     .toast .modal .modal__panel
     .skeleton .mono .kicker .empty .reveal

   Plus the things the five shipped views actually need and the contract took
   as read: .icon, .avatar, .ledger, .approval, .thread/.msg, .composer,
   .toolbar, .suggest, .divider, .callout, .disclosure.

   Status -> class mapping (keep in sync with js/core/status.js):
     approved | auto_approved              -> ok
     pending                               -> warn
     rejected                              -> bad
     blocked_no_approver
     blocked_insufficient_balance          -> info   (held: nothing was applied)
     everything else                       -> neutral
   ========================================================================= */

/* =============================================================================
   Kicker / mono — the UI Kit's label voice
   ========================================================================= */

.kicker{
  font-family:var(--font-data);
  font-size:var(--fs-mono-label);
  font-weight:var(--fw-medium);
  line-height:1.4;
  letter-spacing:var(--ls-kicker);
  text-transform:uppercase;
  color:var(--text-2);
  /* .18em tracking adds a phantom space after the last glyph; pull it back so
     the label optically left-aligns with the number under it. */
  margin-inline-end:calc(-1 * var(--ls-kicker));
}
/* Vanik Data is ASCII-only by design; an Armenian kicker falls through to
   Vanik Text, where .18em uppercase tracking is wrong for the script. */
:lang(hy) .kicker{ font-family:var(--font-text); letter-spacing:.06em; text-transform:none; }

.mono{ font-family:var(--font-data); font-variant-numeric:tabular-nums lining-nums; }
.num{ font-family:var(--font-data); font-variant-numeric:tabular-nums lining-nums;
      font-feature-settings:"ss01"; }

/* =============================================================================
   Icons — /static/icons.svg, two families.
     ui-*  monochrome, 24 grid, stroke:currentColor   (chrome)
     ic-*  branded badge, 64 grid, own colours        (leave types, statuses)
   ========================================================================= */

.icon{
  width:20px; height:20px;
  flex:0 0 auto;
  display:block;
  fill:none;
  stroke:currentColor;
  vertical-align:middle;
  pointer-events:none;
}
.icon--sm{ width:16px; height:16px; }
.icon--lg{ width:24px; height:24px; }
/* Badge icons carry their own fills; do not tint them. */
.icon--badge{ fill:currentColor; stroke:none; border-radius:var(--r-chip); }

/* =============================================================================
   Buttons
   ========================================================================= */

.btn{
  --btn-h:40px;
  position:relative;
  isolation:isolate;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  min-height:var(--btn-h);
  padding-inline:var(--sp-4);
  border:1px solid transparent;
  border-radius:var(--r-btn);
  background:var(--surface-2);
  color:var(--text);
  font-family:var(--font-text);
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  line-height:1.2;
  letter-spacing:.004em;
  text-align:center;
  text-decoration:none;
  white-space:nowrap;
  cursor:pointer;
  user-select:none;
  transition:background var(--dur-1) var(--ease),
             border-color var(--dur-1) var(--ease),
             color var(--dur-1) var(--ease),
             box-shadow var(--dur-1) var(--ease);
}
.btn:disabled,.btn[aria-disabled="true"]{ opacity:.45; cursor:not-allowed; }
.btn:not(:disabled):active{ transform:translateY(.5px); }

/* size scale — 40 default, 48 large, 32 small */
.btn--lg{ --btn-h:48px; padding-inline:var(--sp-5); font-size:var(--fs-body); }
.btn--sm{ --btn-h:32px; padding-inline:var(--sp-3); font-size:var(--fs-xs); gap:var(--sp-1); }
.btn--icon{ padding-inline:0; width:var(--btn-h); }
.btn--block{ display:flex; width:100%; }

/* primary — solid brand. --on-accent, NOT --ink: --ink flips white in the
   light theme and white-on-cyan is 2.5:1. */
.btn--primary{
  background:var(--cyan);
  border-color:var(--cyan);
  color:var(--on-accent);
}
.btn--primary:hover:not(:disabled){ background:var(--cyan-hot); border-color:var(--cyan-hot); }
.btn--primary:active:not(:disabled){ background:var(--cyan-deep); border-color:var(--cyan-deep); }

/* ghost — the default for secondary actions; hairline, not a slab */
.btn--ghost{
  background:transparent;
  border-color:var(--line);
  color:var(--text-2);
}
.btn--ghost:hover:not(:disabled){
  background:var(--overlay-1);
  border-color:var(--line-2);
  color:var(--text);
}

/* quiet — no border at all, for toolbar-adjacent actions */
.btn--quiet{ background:transparent; border-color:transparent; color:var(--text-2); }
.btn--quiet:hover:not(:disabled){ background:var(--overlay-1); color:var(--text); }

/* danger / approve — tinted, never a saturated slab. White on --bad is 3.8:1
   and white on --ok is 3.2:1; the tint + `-fg` pairing clears AA instead. */
.btn--danger{
  background:transparent;
  border-color:var(--bad-line);
  color:var(--bad-fg);
}
.btn--danger:hover:not(:disabled){ background:var(--bad-weak); border-color:var(--bad); }

.btn--ok{
  background:transparent;
  border-color:var(--ok-line);
  color:var(--ok-fg);
}
.btn--ok:hover:not(:disabled){ background:var(--ok-weak); border-color:var(--ok); }

/* --- .btn--flood — the Studio One signature -------------------------------

   At rest: a cyan chip inset by --flood-inset on the left, the label static to
   its right. On hover/focus the chip FLOODS to the full button with the same
   inset on all four sides, and the label — which has not moved a pixel —
   reads on cyan.

   The UI Kit measured the label in JS to do this. It does not need to: an
   inset() clip-path on a full-bleed pseudo-element interpolates smoothly,
   holds `round var(--r-btn)` exactly at both ends (a scaleX would smear the
   radius), and keeps the inset even by construction. Both keyframes are
   written with all four inset components so the interpolation is unambiguous.
   ---------------------------------------------------------------------- */

.btn--flood{
  --flood-w:calc(var(--btn-h) - 2 * var(--flood-inset));
  justify-content:flex-start;
  padding-inline:calc(var(--btn-h) + var(--sp-2)) var(--sp-4);
  background:var(--surface-2);
  border-color:var(--line);
  color:var(--text);
  overflow:hidden;
}
.btn--flood::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;                     /* above the button background, below the label */
  background:var(--cyan);
  clip-path:inset(var(--flood-inset)
                  calc(100% - var(--flood-inset) - var(--flood-w))
                  var(--flood-inset)
                  var(--flood-inset)
                  round var(--r-btn));
}
.btn--flood .btn__ico{
  position:absolute;
  inset-block:var(--flood-inset);
  inset-inline-start:var(--flood-inset);
  width:var(--flood-w);
  display:grid;
  place-items:center;
  color:var(--on-accent);
  pointer-events:none;
}
.btn--flood:hover:not(:disabled),
.btn--flood:focus-visible{
  border-color:var(--cyan);
  color:var(--on-accent);
}
.btn--flood:hover:not(:disabled)::before,
.btn--flood:focus-visible::before{
  clip-path:inset(var(--flood-inset) var(--flood-inset)
                  var(--flood-inset) var(--flood-inset)
                  round var(--r-btn));
}
.btn--flood:disabled::before{ background:var(--neutral); }

@media (prefers-reduced-motion: no-preference){
  .btn--flood::before{
    transition:clip-path var(--dur-2) var(--ease-out),
               background var(--dur-1) var(--ease);
  }
}

/* =============================================================================
   Chips (filters, tags) and badges (status)
   ========================================================================= */

.chip{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-1);
  padding:5px 11px;
  border:1px solid var(--neutral-line);
  border-radius:var(--r-pill);
  background:var(--neutral-weak);
  color:var(--text-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  line-height:1.35;
  white-space:nowrap;
  transition:background var(--dur-1) var(--ease),
             border-color var(--dur-1) var(--ease),
             color var(--dur-1) var(--ease);
}
button.chip,a.chip,.chip[role="button"]{ cursor:pointer; }
button.chip:hover,a.chip:hover{ border-color:var(--line-2); color:var(--text); }

.chip--ok     { background:var(--ok-weak);      border-color:var(--ok-line);      color:var(--ok-fg); }
.chip--info   { background:var(--info-weak);    border-color:var(--info-line);    color:var(--info-fg); }
.chip--warn   { background:var(--warn-weak);    border-color:var(--warn-line);    color:var(--warn-fg); }
.chip--bad    { background:var(--bad-weak);     border-color:var(--bad-line);     color:var(--bad-fg); }
.chip--neutral{ background:var(--neutral-weak); border-color:var(--neutral-line); color:var(--neutral-fg); }
.chip--accent { background:var(--cyan-weak);    border-color:var(--cyan-line);    color:var(--link); }

.chip[aria-pressed="true"],.chip.is-active{
  background:var(--cyan-weak); border-color:var(--cyan-line); color:var(--link);
}
.chips{ display:flex; flex-wrap:wrap; gap:var(--sp-2); }

.badge{
  display:inline-flex;
  align-items:center;
  gap:var(--sp-1);
  padding:3px 9px;
  border-radius:var(--r-pill);
  background:var(--neutral-weak);
  color:var(--neutral-fg);
  font-size:var(--fs-2xs);
  font-weight:var(--fw-bold);
  line-height:1.5;
  letter-spacing:var(--ls-wide);
  white-space:nowrap;
}
.badge--ok     { background:var(--ok-weak);      color:var(--ok-fg); }
.badge--info   { background:var(--info-weak);    color:var(--info-fg); }
.badge--warn   { background:var(--warn-weak);    color:var(--warn-fg); }
.badge--bad    { background:var(--bad-weak);     color:var(--bad-fg); }
.badge--neutral{ background:var(--neutral-weak); color:var(--neutral-fg); }
/* A held request — no approver chain, or approved but unpayable — is neither
   green nor red nor simply waiting. The ring says "someone must act". */
.badge--info{ box-shadow:inset 0 0 0 1px var(--info-line); }

.badge--dot::before{
  content:"";
  width:6px; height:6px;
  border-radius:var(--r-pill);
  background:currentColor;
  flex:0 0 auto;
}

/* =============================================================================
   Cards
   ========================================================================= */

.card{
  display:flex;
  flex-direction:column;
  min-width:0;
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-card);
  box-shadow:var(--shadow-1);
}
.card__head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);
  border-block-end:1px solid var(--line);
  min-width:0;
}
.card__title{
  font-family:var(--font-display);
  font-size:var(--fs-h3);
  font-weight:var(--fw-semi);
  letter-spacing:var(--ls-tight);
  line-height:var(--lh-snug);
  min-width:0;
}
.card__body{ padding:var(--sp-5); flex:1 1 auto; min-width:0; }
.card__foot{
  padding:var(--sp-3) var(--sp-5);
  border-block-start:1px solid var(--line);
  background:var(--surface-2);
  border-end-start-radius:var(--r-card);
  border-end-end-radius:var(--r-card);
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  font-size:var(--fs-sm);
  color:var(--text-2);
}
/* A card with no head is just a padded surface. */
.card--flat{ box-shadow:none; }
.card--accent{ border-color:var(--cyan-line); }
a.card,button.card{ text-align:start; cursor:pointer;
  transition:border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease); }
a.card:hover,button.card:hover{ border-color:var(--line-2); background:var(--surface-2); }

.divider{ height:1px; background:var(--line); border:0; margin-block:var(--sp-4); }

/* =============================================================================
   Metric — the number a manager actually came for
   ========================================================================= */

.metric{ display:grid; gap:var(--sp-1); min-width:0; }
.metric__label{
  font-family:var(--font-data);
  font-size:var(--fs-mono-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--ls-kicker);
  text-transform:uppercase;
  color:var(--text-2);
  order:-1;
}
:lang(hy) .metric__label{ font-family:var(--font-text); letter-spacing:.06em; text-transform:none; }
.metric__row{ display:flex; align-items:baseline; gap:var(--sp-2); flex-wrap:wrap; }
.metric__num{
  font-family:var(--font-data);
  font-size:var(--fs-metric);
  font-weight:var(--fw-semi);
  font-variant-numeric:tabular-nums lining-nums;
  line-height:1.05;
  letter-spacing:-.02em;
  color:var(--text);
  /* count-up must not reflow the row as digits change */
  font-feature-settings:"tnum" 1;
}
.metric__unit{ font-size:var(--fs-sm); color:var(--text-3); }
.metric__delta{ font-size:var(--fs-sm); font-family:var(--font-data); }
.metric__delta--up{ color:var(--ok-fg); }
.metric__delta--down{ color:var(--bad-fg); }
/* the notifier.py `~~20~~ **19** left` idiom, in CSS */
.metric__was{ color:var(--text-3); text-decoration:line-through; font-size:var(--fs-sm); }

/* =============================================================================
   Meter — the balance bar. FILLED = REMAINING (notifier.py:158, deliberately).
   ========================================================================= */

.meter{
  height:8px;
  border-radius:var(--r-pill);
  background:var(--track);
  overflow:hidden;
  margin-block-start:var(--sp-3);
}
.meter__fill{
  display:block;
  height:100%;
  width:0;
  border-radius:var(--r-pill);
  background:linear-gradient(90deg,var(--cyan-deep),var(--cyan));
}
.meter--ok  .meter__fill{ background:linear-gradient(90deg,var(--ok),var(--viz-8)); }
.meter--warn .meter__fill{ background:linear-gradient(90deg,var(--warn),var(--viz-7)); }
.meter--bad .meter__fill{ background:linear-gradient(90deg,var(--bad),var(--viz-5)); }
.meter--lg{ height:12px; }
/* Stacked used / pending / available, in one track. */
.meter--stack{ display:flex; }
.meter--stack .meter__fill{ border-radius:0; }
.meter--stack .meter__fill:first-child{ border-start-start-radius:var(--r-pill);
                                        border-end-start-radius:var(--r-pill); }
.meter--stack .meter__fill:last-child{ border-start-end-radius:var(--r-pill);
                                       border-end-end-radius:var(--r-pill); }
.meter__fill--pending{ background:var(--warn); opacity:.55; }
.meter__fill--used{ background:var(--neutral); }

@media (prefers-reduced-motion: no-preference){
  .meter__fill{ transition:width var(--dur-3) var(--ease-out); }
}

/* =============================================================================
   Fields
   ========================================================================= */

.field{ display:grid; gap:6px; min-width:0; }
.field--inline{ grid-auto-flow:column; align-items:center; gap:var(--sp-2); }
.field__label{
  font-size:var(--fs-sm);
  font-weight:var(--fw-semi);
  color:var(--text-2);
  line-height:var(--lh-snug);
}
.field__label .req{ color:var(--bad-fg); margin-inline-start:2px; }
.field__input{
  width:100%;
  min-height:40px;
  padding:var(--sp-2) var(--sp-3);
  background:var(--surface-2);
  color:var(--text);
  border:1px solid var(--line);
  border-radius:var(--r-chip-lg);
  font-family:var(--font-text);
  font-size:var(--fs-sm);
}
.field__input:hover:not(:disabled){ border-color:var(--line-2); }
.field__input:focus{
  border-color:var(--cyan);
  background:var(--surface-3);
  box-shadow:0 0 0 3px var(--cyan-weak);
  outline:none;
}
.field__hint{ font-size:var(--fs-xs); color:var(--text-3); line-height:var(--lh-snug); }
.field__err{ font-size:var(--fs-xs); color:var(--bad-fg); min-height:1.15em; line-height:var(--lh-snug); }
.field.is-invalid .field__input,
.field__input[aria-invalid="true"]{ border-color:var(--bad); }
.field.is-invalid .field__input:focus{ box-shadow:0 0 0 3px var(--bad-weak); }

.fieldset{ display:grid; gap:var(--sp-4); }
.fieldset--row{ grid-auto-flow:column; grid-auto-columns:minmax(0,1fr); }
@media (max-width:640px){ .fieldset--row{ grid-auto-flow:row; } }

/* =============================================================================
   Toolbar
   ========================================================================= */

.toolbar{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:var(--sp-2);
  margin-block-end:var(--sp-5);
}
.toolbar select,
.toolbar input,
.toolbar .field__input{ width:auto; min-width:140px; }
.toolbar__sep{ width:1px; align-self:stretch; background:var(--line); margin-inline:var(--sp-1); }

/* =============================================================================
   Tables
   ========================================================================= */

.table{
  width:100%;
  border-collapse:collapse;
  font-size:var(--fs-sm);
}
.table th{
  font-family:var(--font-data);
  font-size:var(--fs-mono-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--ls-kicker);
  text-transform:uppercase;
  color:var(--text-2);
  text-align:start;
  padding:var(--sp-2) var(--sp-3);
  border-block-end:1px solid var(--line-2);
  white-space:nowrap;
}
:lang(hy) .table th{ font-family:var(--font-text); letter-spacing:.04em; text-transform:none; }
.table td{
  padding:var(--sp-3);
  border-block-end:1px solid var(--line);
  vertical-align:top;
  color:var(--text);
}
.table tbody tr:last-child td{ border-block-end:0; }
.table tbody tr:hover td{ background:var(--overlay-1); }
.table td.num,.table th.num{
  font-family:var(--font-data);
  font-variant-numeric:tabular-nums lining-nums;
  text-align:end;
}
.table--dense th{ padding:var(--sp-1) var(--sp-2); }
.table--dense td{ padding:var(--sp-2); }
.table caption{
  caption-side:bottom;
  padding-block-start:var(--sp-2);
  color:var(--text-3);
  font-size:var(--fs-xs);
  text-align:start;
}
.table-wrap{ overflow-x:auto; overscroll-behavior-x:contain; }

/* =============================================================================
   Tabs
   ========================================================================= */

.tabs{
  display:flex;
  flex-wrap:wrap;
  gap:var(--sp-2);
  margin-block-end:var(--sp-4);
}
.tabs__tab{
  padding:6px 13px;
  border:1px solid var(--line);
  border-radius:var(--r-pill);
  background:transparent;
  color:var(--text-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  white-space:nowrap;
  cursor:pointer;
  transition:background var(--dur-1) var(--ease),
             border-color var(--dur-1) var(--ease),
             color var(--dur-1) var(--ease);
}
.tabs__tab:hover{ border-color:var(--line-2); color:var(--text); }
.tabs__tab[aria-selected="true"],
.tabs__tab.is-active{
  background:var(--cyan-weak);
  border-color:var(--cyan-line);
  color:var(--link);
}
.tabs--underline{ gap:var(--sp-5); border-block-end:1px solid var(--line); margin-block-end:var(--sp-5); }
.tabs--underline .tabs__tab{
  border:0; border-radius:0; padding:var(--sp-2) 0;
  border-block-end:2px solid transparent;
  font-size:var(--fs-sm); background:none;
}
.tabs--underline .tabs__tab[aria-selected="true"]{
  background:none; color:var(--text); border-block-end-color:var(--cyan);
}

/* =============================================================================
   Rail (left nav) — placement lives in layout.css, appearance here
   ========================================================================= */

.rail__wordmark{
  font-family:var(--font-display);
  font-size:var(--fs-body);
  font-weight:var(--fw-bold);
  letter-spacing:var(--ls-tight);
  color:var(--text);
  min-width:0;
}
.rail__wordmark em{ font-style:normal; font-weight:var(--fw-regular); color:var(--text-3); }
.rail__mark{
  display:grid;
  place-items:center;
  width:28px; height:28px;
  flex:0 0 auto;
  border-radius:var(--r-chip);
  background:var(--cyan);
  color:var(--on-accent);
  font-family:var(--font-display);
  font-weight:var(--fw-bold);
  font-size:var(--fs-sm);
  line-height:1;
}

.rail__item{
  position:relative;
  display:grid;
  grid-template-columns:20px minmax(0,1fr) auto;
  align-items:center;
  gap:var(--sp-3);
  width:100%;
  min-height:38px;
  padding:var(--sp-2) var(--sp-3);
  border-radius:var(--r-chip-lg);
  color:var(--text-2);
  font-size:var(--fs-sm);
  font-weight:var(--fw-medium);
  text-align:start;
  text-decoration:none;
  cursor:pointer;
  transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.rail__item:hover{ background:var(--overlay-1); color:var(--text); }
.rail__item--active,
.rail__item[aria-current="page"]{
  background:var(--cyan-weak);
  color:var(--text);
  font-weight:var(--fw-semi);
}
/* the active marker: a 3px cyan bar on the inline edge, not a filled slab */
.rail__item--active::before,
.rail__item[aria-current="page"]::before{
  content:"";
  position:absolute;
  inset-inline-start:calc(-1 * var(--sp-2));
  inset-block:6px;
  width:3px;
  border-radius:var(--r-pill);
  background:var(--cyan);
}
.rail__item--active .icon,
.rail__item[aria-current="page"] .icon{ color:var(--cyan); }
.rail__label{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rail__group{ padding:var(--sp-4) var(--sp-3) var(--sp-1); }
.rail__who{ color:var(--text); font-weight:var(--fw-semi); font-size:var(--fs-sm);
            overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.rail__meta{ color:var(--text-3); font-size:var(--fs-xs); }

/* =============================================================================
   Ledger — the compact "one row per record" list the dashboard uses
   ========================================================================= */

.ledger{ list-style:none; display:flex; flex-direction:column; gap:var(--sp-2); padding:0; margin:0; }
.ledger li,
.ledger__item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-3);
  min-width:0;
  padding:var(--sp-2) var(--sp-3);
  border:1px solid var(--line);
  border-radius:var(--r-chip-lg);
  background:var(--surface-2);
  font-size:var(--fs-sm);
}
.ledger__main{ min-width:0; display:grid; gap:1px; }
.ledger__label{ color:var(--text); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ledger__meta{ color:var(--text-3); font-size:var(--fs-xs); }
.ledger__val{ font-family:var(--font-data); font-variant-numeric:tabular-nums; white-space:nowrap; }

/* =============================================================================
   Approval row
   ========================================================================= */

.approval{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-3) var(--sp-4);
  padding:var(--sp-4);
  margin-block-end:var(--sp-2);
  border:1px solid var(--line);
  border-radius:var(--r-btn);
  background:var(--surface-1);
  transition:border-color var(--dur-1) var(--ease);
}
.approval:hover{ border-color:var(--line-2); }
.approval__main,
.approval .body{ min-width:0; display:grid; gap:3px; flex:1 1 260px; }
.approval__who,
.approval .who{ font-weight:var(--fw-semi); color:var(--text); }
.approval__meta,
.approval .meta{ color:var(--text-2); font-size:var(--fs-sm); }
.approval__actions,
.approval .actions{ display:flex; flex-wrap:wrap; gap:var(--sp-2); }
/* A held row wears its state on the edge, so a queue scans at a glance. */
.approval--held{ border-inline-start:3px solid var(--info); }
.approval--pending{ border-inline-start:3px solid var(--warn); }

/* =============================================================================
   Chat — thread, message, composer
   ========================================================================= */

.thread{
  max-width:var(--thread-max);
  margin-inline:auto;
  padding-inline:max(var(--sp-5),env(safe-area-inset-left))
                 max(var(--sp-5),env(safe-area-inset-right));
  display:flex;
  flex-direction:column;
  gap:var(--sp-6);
}

.msg{ display:flex; gap:var(--sp-3); align-items:flex-start; min-width:0; }
.msg__av,
.msg .av{
  flex:0 0 30px;
  width:30px; height:30px;
  margin-block-start:2px;
  border-radius:var(--r-chip);
  display:grid;
  place-items:center;
  font-family:var(--font-display);
  font-weight:var(--fw-bold);
  font-size:var(--fs-xs);
  line-height:1;
}
.msg--user .msg__av,.msg.user .av{ background:var(--surface-3); color:var(--text); }
.msg--assistant .msg__av,.msg.assistant .av{ background:var(--cyan); color:var(--on-accent); }
.msg__body,.msg .body{ flex:1 1 auto; min-width:0; }
.msg__name,.msg .name{
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  color:var(--text-2);
  margin-block-end:3px;
}
.msg__content,.msg .content{
  font-size:var(--fs-body);
  line-height:var(--lh-loose);
  color:var(--text);
  overflow-wrap:break-word;
  white-space:pre-wrap;
}
.msg__content > *:first-child{ margin-block-start:0; }
.msg__content h1,.msg__content h2,.msg__content h3,
.msg .content h1,.msg .content h2,.msg .content h3{ margin:.7em 0 .3em; }
.msg__content ul,.msg__content ol,.msg .content ul,.msg .content ol{ padding-inline-start:1.3em; }
.msg__content code,.msg .content code{ background:var(--code-bg); }
.msg__content table,.msg .content table{
  border-collapse:collapse; margin:.6em 0; font-size:var(--fs-sm); width:100%;
}
.msg__content th,.msg__content td,
.msg .content th,.msg .content td{ border:1px solid var(--line); padding:5px 9px; text-align:start; }
.msg__content th,.msg .content th{ background:var(--surface-2); color:var(--text-2); }
.msg__content a,.msg .content a{ text-decoration:underline; }

.msg__tools,.msg .tools{
  display:flex; flex-wrap:wrap; gap:var(--sp-1);
  margin-block-start:var(--sp-2);
  font-size:var(--fs-xs); color:var(--text-3);
}
.msg__tool,.msg .tools .t{
  font-family:var(--font-data);
  background:var(--cyan-weak);
  color:var(--link);
  border-radius:var(--r-chip);
  padding:2px 7px;
  font-weight:var(--fw-medium);
}

.msg__actions{
  display:flex; flex-wrap:wrap; gap:var(--sp-2);
  margin-block-start:var(--sp-3);
}
/* Match suggestion chips so Yes/No/Reply stay obvious on dark theme. */
.msg__action{
  appearance:none; border:1px solid var(--cyan-line);
  background:color-mix(in srgb, var(--cyan) 12%, var(--surface-2));
  color:var(--text); border-radius:var(--r-chip); padding:8px 14px;
  font:inherit; font-size:var(--fs-sm); font-weight:var(--fw-medium);
  cursor:pointer; line-height:1.2;
}
.msg__action:hover{ border-color:var(--cyan); background:color-mix(in srgb, var(--cyan) 22%, var(--surface-2)); }
.msg__action:disabled{ opacity:0.55; cursor:default; }
.msg__action--success{
  background:color-mix(in srgb, #2ea043 28%, var(--surface-2));
  border-color:color-mix(in srgb, #2ea043 70%, var(--line));
  color:var(--text);
}
.msg__action--primary{
  background:color-mix(in srgb, var(--cyan) 28%, var(--surface-2));
  border-color:var(--cyan);
}
.msg__action--ghost{
  background:var(--surface-2); border-color:var(--line); color:var(--text-2);
}
.msg__reply-hint{
  margin-block-start:var(--sp-2); font-size:var(--fs-sm);
  color:var(--text-2); font-style:italic;
}
.msg--assistant.is-reply-armed{
  outline:1px solid color-mix(in srgb, #2ea043 45%, transparent);
  border-radius:var(--r-md, 10px);
}

.typing{ display:inline-flex; gap:4px; align-items:center; height:1.5em; }
.typing i{ width:6px; height:6px; border-radius:50%; background:var(--cyan); opacity:.45; }
@media (prefers-reduced-motion: no-preference){
  .typing i{ animation:vk-bounce 1s infinite; }
  .typing i:nth-child(2){ animation-delay:.15s; }
  .typing i:nth-child(3){ animation-delay:.3s; }
}
@keyframes vk-bounce{
  0%,80%,100%{ transform:translateY(0); opacity:.4; }
  40%        { transform:translateY(-5px); opacity:1; }
}

.composer{
  flex:0 0 auto;
  border-block-start:1px solid var(--line);
  background:var(--surface-1);
  padding:var(--sp-3) var(--sp-5)
          max(var(--sp-3),env(safe-area-inset-bottom));
}
.composer__box,
.composer .box{
  max-width:var(--thread-max);
  margin-inline:auto;
  display:flex;
  align-items:flex-end;
  gap:var(--sp-2);
  padding:var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-card);
  background:var(--surface-2);
  transition:border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.composer__box:focus-within,
.composer .box:focus-within{ border-color:var(--cyan-line); box-shadow:0 0 0 3px var(--cyan-weak); }
.composer textarea{
  flex:1 1 auto;
  border:0; background:none; box-shadow:none;
  min-height:38px; max-height:180px;
  padding:var(--sp-2) 0;
  resize:none;
  font-size:var(--fs-body);
  line-height:var(--lh);
}
.composer textarea:focus{ box-shadow:none; background:none; border:0; }
.composer__send,
.composer .send{
  flex:0 0 38px;
  width:38px; height:38px;
  display:grid; place-items:center;
  border-radius:var(--r-btn);
  background:var(--cyan);
  color:var(--on-accent);
  cursor:pointer;
  transition:background var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease);
}
.composer__send:hover:not(:disabled),.composer .send:hover:not(:disabled){ background:var(--cyan-hot); }
.composer__send:disabled,.composer .send:disabled{ opacity:.35; cursor:default; }
/* The persistent §3.4 line under the composer — never hidden, never a toast. */
.composer__note{
  max-width:var(--thread-max);
  margin:var(--sp-2) auto 0;
  text-align:center;
  font-size:var(--fs-xs);
  color:var(--text-3);
  line-height:var(--lh-snug);
}

/* Chat list rows */
.chat__item,
.chat-list .item{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--sp-2);
  padding:var(--sp-2) var(--sp-3);
  border-radius:var(--r-chip-lg);
  color:var(--text-2);
  font-size:var(--fs-sm);
  cursor:pointer;
  min-width:0;
  white-space:nowrap;
  transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.chat__item > span,
.chat-list .item > span{ overflow:hidden; text-overflow:ellipsis; min-width:0; }
.chat__item:hover,.chat-list .item:hover{ background:var(--overlay-1); color:var(--text); }
.chat__item.is-active,.chat-list .item.active{
  background:var(--surface-3); color:var(--text); font-weight:var(--fw-semi);
}
.chat__del,
.chat-list .item .del{
  opacity:0; color:var(--text-3); padding:0 var(--sp-1); flex:0 0 auto;
  transition:opacity var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.chat__item:hover .chat__del,.chat-list .item:hover .del{ opacity:1; }
.chat__del:hover,.chat-list .item .del:hover{ color:var(--bad-fg); }
.chat__del:focus-visible{ opacity:1; }

.role-tabs{ display:flex; flex-wrap:wrap; gap:var(--sp-1); padding:0 var(--sp-3) var(--sp-2); }

/* Suggestion cards on the empty chat */
.suggest{ display:flex; flex-wrap:wrap; gap:var(--sp-3); justify-content:center; margin-block-start:var(--sp-5); }
.suggest button{
  max-width:270px;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-btn);
  background:var(--surface-1);
  color:var(--text-2);
  font-size:var(--fs-sm);
  text-align:start;
  line-height:var(--lh-snug);
  cursor:pointer;
  transition:border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease),
             background var(--dur-1) var(--ease);
}
.suggest button:hover{ border-color:var(--cyan-line); color:var(--text); background:var(--surface-2); }

/* =============================================================================
   Callout / disclosure
   ========================================================================= */

.callout{
  display:flex;
  gap:var(--sp-3);
  align-items:flex-start;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line);
  border-radius:var(--r-btn);
  background:var(--surface-1);
  font-size:var(--fs-sm);
  color:var(--text-2);
  line-height:var(--lh-snug);
}
.callout--info{ border-color:var(--info-line); background:var(--info-weak); }
.callout--warn{ border-color:var(--warn-line); background:var(--warn-weak); }
.callout--bad { border-color:var(--bad-line);  background:var(--bad-weak); }
.callout .icon{ margin-block-start:2px; }

/* The Handbook §3.4 confidentiality bar. It is chrome, not a toast: it stays
   until dismissed and it is the only place the disclosure is made on the web. */
.disclosure{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:var(--sp-3);
  margin-block-end:var(--sp-5);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-2);
  border-radius:var(--r-btn);
  background:var(--surface-2);
  font-size:var(--fs-xs);
  color:var(--text-2);
  line-height:var(--lh-snug);
}
.disclosure > .btn{ margin-inline-start:auto; }

/* =============================================================================
   Empty state
   ========================================================================= */

.empty{
  display:grid;
  gap:var(--sp-2);
  justify-items:center;
  text-align:center;
  max-width:640px;
  margin-inline:auto;
  padding:var(--sp-9) var(--sp-4);
  color:var(--text-2);
}
.empty__title,
.empty h2{
  font-family:var(--font-display);
  font-size:var(--fs-h1);
  font-weight:var(--fw-semi);
  letter-spacing:var(--ls-tight);
  color:var(--text);
}
.empty .icon{ width:32px; height:32px; color:var(--text-3); margin-block-end:var(--sp-2); }

/* =============================================================================
   Avatar
   ========================================================================= */

.avatar{
  display:grid; place-items:center;
  width:28px; height:28px; flex:0 0 auto;
  border-radius:var(--r-pill);
  background:var(--surface-3);
  color:var(--text-2);
  font-size:var(--fs-xs);
  font-weight:var(--fw-semi);
  overflow:hidden;
}
.avatar--lg{ width:40px; height:40px; font-size:var(--fs-sm); }

/* =============================================================================
   Skeleton
   ========================================================================= */

.skeleton{
  --sk-h:1em;
  display:block;
  height:var(--sk-h);
  min-height:12px;
  border-radius:var(--r-chip);
  background:var(--skeleton-1);
  color:transparent;
  user-select:none;
  pointer-events:none;
}
.skeleton--text{ --sk-h:.85em; margin-block:.3em; }
.skeleton--line-2{ width:72%; }
.skeleton--line-3{ width:46%; }
.skeleton--card{ --sk-h:120px; border-radius:var(--r-card); }
.skeleton--circle{ --sk-h:28px; width:28px; border-radius:var(--r-pill); }

@media (prefers-reduced-motion: no-preference){
  .skeleton{
    background:linear-gradient(90deg,
      var(--skeleton-1) 0%, var(--skeleton-2) 42%, var(--skeleton-1) 84%);
    background-size:280% 100%;
    animation:vk-shimmer 1.5s var(--ease) infinite;
  }
}
@keyframes vk-shimmer{ from{ background-position:120% 0; } to{ background-position:-120% 0; } }

/* =============================================================================
   Toast
   ========================================================================= */

.toasts{
  position:fixed;
  inset-block-end:max(var(--sp-5),env(safe-area-inset-bottom));
  inset-inline-end:max(var(--sp-5),env(safe-area-inset-right));
  z-index:60;
  display:flex;
  flex-direction:column;
  gap:var(--sp-2);
  pointer-events:none;
  max-width:min(400px,calc(100vw - 2 * var(--sp-4)));
}
.toast{
  pointer-events:auto;
  display:flex;
  align-items:flex-start;
  gap:var(--sp-3);
  padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-2);
  border-radius:var(--r-btn);
  background:var(--surface-3);
  color:var(--text);
  box-shadow:var(--shadow-2);
  font-size:var(--fs-sm);
  line-height:var(--lh-snug);
}
.toast--ok  { border-color:var(--ok-line);   }
.toast--warn{ border-color:var(--warn-line); }
.toast--bad { border-color:var(--bad-line);  }
.toast__close{ margin-inline-start:auto; color:var(--text-3); flex:0 0 auto; }
.toast__close:hover{ color:var(--text); }

@media (prefers-reduced-motion: no-preference){
  .toast{ animation:vk-toast-in var(--dur-2) var(--ease-out) both; }
}
@keyframes vk-toast-in{
  from{ opacity:0; transform:translateY(8px) scale(.98); }
  to  { opacity:1; transform:none; }
}

/* =============================================================================
   Modal
   ========================================================================= */

.modal{
  position:fixed;
  inset:0;
  z-index:70;
  display:grid;
  place-items:center;
  padding:var(--sp-4);
  background:var(--scrim);
  -webkit-backdrop-filter:blur(2px);
  backdrop-filter:blur(2px);
}
.modal[hidden]{ display:none; }
.modal__panel{
  width:min(560px,100%);
  max-height:min(86vh,720px);
  display:flex;
  flex-direction:column;
  overflow:hidden;
  background:var(--surface-1);
  border:1px solid var(--line-2);
  border-radius:var(--r-card);
  box-shadow:var(--shadow-2);
}
.modal__head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);
  border-block-end:1px solid var(--line);
}
.modal__title{ font-family:var(--font-display); font-size:var(--fs-h3); font-weight:var(--fw-semi); }
.modal__body{ padding:var(--sp-5); overflow-y:auto; min-height:0; }
.modal__foot{
  display:flex; justify-content:flex-end; gap:var(--sp-2);
  padding:var(--sp-3) var(--sp-5);
  border-block-start:1px solid var(--line);
  background:var(--surface-2);
}
dialog.modal__panel::backdrop{ background:var(--scrim); }

/* Checkbox list (admin Roles modal) — dense 2-col grid inside the panel body. */
.check-list{
  border:0; margin:0; padding:0;
  display:grid; gap:var(--sp-3); min-width:0;
}
.check-list > .field__label{ margin:0; padding:0; }
.check-list__grid{
  display:grid;
  grid-template-columns:repeat(2, minmax(0, 1fr));
  gap:var(--sp-1) var(--sp-4);
  max-height:min(50vh, 420px);
  overflow-y:auto;
  padding-inline-end:var(--sp-1);
}
.check-list__item{
  display:flex; align-items:center; gap:var(--sp-2);
  font-size:var(--fs-sm); color:var(--text);
  cursor:pointer; user-select:none;
  padding:var(--sp-1) 0; min-width:0;
}
.check-list__item span{
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.check-list__item input[type="checkbox"]{
  width:1rem; height:1rem; flex-shrink:0;
  accent-color:var(--cyan);
  cursor:pointer;
}
@media (max-width:420px){
  .check-list__grid{ grid-template-columns:1fr; }
}

/* Ordered people picker (admin Approver chain modal). */
.people-picker{ display:grid; gap:var(--sp-3); min-width:0; }
.people-picker__chain{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:var(--sp-2);
  min-height:2.5rem;
}
.people-picker__empty{
  padding:var(--sp-3); border:1px dashed var(--line);
  border-radius:var(--r-chip-lg); text-align:center;
}
.people-picker__chip{
  display:flex; align-items:center; gap:var(--sp-2);
  padding:var(--sp-2) var(--sp-3);
  background:var(--code-bg); border:1px solid var(--line);
  border-radius:var(--r-chip-lg); min-width:0;
}
.people-picker__ord{
  flex-shrink:0; width:1.4rem; height:1.4rem;
  display:grid; place-items:center;
  font-size:var(--fs-xs); font-weight:var(--fw-semi);
  color:var(--on-accent); background:var(--cyan);
  border-radius:var(--r-chip);
}
.people-picker__name{
  flex:1; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:var(--fs-sm); color:var(--text);
}
.people-picker__chip .btn--icon{
  flex-shrink:0; width:1.75rem; height:1.75rem; padding:0;
  color:var(--text-2);
}
.people-picker__chip .btn--icon:disabled{ opacity:.35; cursor:default; }
.people-picker__search{ position:relative; min-width:0; }
.people-picker__list{
  position:absolute; z-index:5; inset-inline:0; top:calc(100% + 4px);
  list-style:none; margin:0; padding:var(--sp-1);
  max-height:min(40vh, 240px); overflow-y:auto;
  background:var(--surface-2);
  border:1px solid var(--line-2); border-radius:var(--r-chip-lg);
  box-shadow:var(--shadow-2);
}
.people-picker__opt{
  padding:var(--sp-2) var(--sp-3);
  border-radius:var(--r-chip);
  font-size:var(--fs-sm); color:var(--text);
  cursor:pointer; user-select:none;
}
.people-picker__opt:hover,
.people-picker__opt.is-active{
  background:var(--cyan-weak); color:var(--link);
}
.people-picker__none{ padding:var(--sp-3); text-align:center; }

@media (prefers-reduced-motion: no-preference){
  .modal{ animation:vk-fade-in var(--dur-1) var(--ease) both; }
  .modal__panel{ animation:vk-panel-in var(--dur-2) var(--ease-out) both; }
}
@keyframes vk-fade-in{ from{opacity:0} to{opacity:1} }
@keyframes vk-panel-in{
  from{ opacity:0; transform:translateY(10px) scale(.985); }
  to  { opacity:1; transform:none; }
}

/* =============================================================================
   Floating action button (compact chat toggle)

   Default: hidden. The chat list is already on-screen at desktop widths; this
   control only opens the off-canvas list under the ≤820px breakpoint in
   layout.css. `display:grid` here used to override layout.css's desktop
   `display:none` (components.css loads later) and left a bright cyan circle
   sat in the chat pane with nothing useful to do.
   ========================================================================= */

.chatfab,.fab{
  display:none;
  place-items:center;
  width:46px; height:46px;
  border-radius:var(--r-pill);
  background:var(--cyan);
  color:var(--on-accent);
  box-shadow:var(--shadow-2);
  cursor:pointer;
  border:0;
}
.chatfab:hover,.fab:hover{ background:var(--cyan-hot); }

/* =============================================================================
   Reveal — motion.js adds .is-revealed via IntersectionObserver.

   The failsafe animation matters more than the transition: if the observer
   never fires (JS error, an ancestor that never intersects, a headless print
   pipeline) the content must still appear. `vk-reveal-failsafe` forces it
   visible at 3s and costs nothing when the observer works, because
   `.is-revealed` sets `animation:none`.
   ========================================================================= */

.reveal{ opacity:1; transform:none; }

@media (prefers-reduced-motion: no-preference){
  .reveal{
    opacity:0;
    transform:translateY(12px);
    transition:opacity var(--dur-3) var(--ease-out),
               transform var(--dur-3) var(--ease-out);
    animation:vk-reveal-failsafe 1ms linear 3s forwards;
    will-change:opacity,transform;
  }
  .reveal.is-revealed{
    opacity:1;
    transform:none;
    animation:none;
    will-change:auto;
  }
  /* stagger: the screen sets --i on each child */
  .reveal{ transition-delay:calc(var(--i,0) * 60ms); }
}
@keyframes vk-reveal-failsafe{ to{ opacity:1; transform:none; } }

@media print{ .reveal{ opacity:1 !important; transform:none !important; animation:none !important; } }

/* =============================================================================
   Compatibility aliases for the five shipped views.

   The P0 port rewrites the markup, but a 1:1 port that keeps a legacy class
   name must not fall through to unstyled. These map the old names onto the new
   components; they are the only place two class systems meet, and they can be
   deleted once the screens are all on contract names.
   ========================================================================= */

.btn-primary,.btn-ghost,.btn-ok,.btn-bad,.btn-discord{
  position:relative; isolation:isolate;
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-height:40px; padding-inline:var(--sp-4);
  border:1px solid transparent; border-radius:var(--r-btn);
  font-family:var(--font-text); font-size:var(--fs-sm); font-weight:var(--fw-semi);
  line-height:1.2; white-space:nowrap; cursor:pointer;
  transition:background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
             color var(--dur-1) var(--ease);
}
.btn-primary{ background:var(--cyan); border-color:var(--cyan); color:var(--on-accent); }
.btn-primary:hover:not(:disabled){ background:var(--cyan-hot); border-color:var(--cyan-hot); }
.btn-ghost{ background:transparent; border-color:var(--line); color:var(--text-2);
            min-height:34px; font-size:var(--fs-xs); }
.btn-ghost:hover{ background:var(--overlay-1); border-color:var(--line-2); color:var(--text); }
.btn-ok{ background:transparent; border-color:var(--ok-line); color:var(--ok-fg);
         min-height:32px; font-size:var(--fs-xs); }
.btn-ok:hover{ background:var(--ok-weak); border-color:var(--ok); }
.btn-bad{ background:transparent; border-color:var(--bad-line); color:var(--bad-fg);
          min-height:32px; font-size:var(--fs-xs); }
.btn-bad:hover{ background:var(--bad-weak); border-color:var(--bad); }
/* Discord's own brand colour is --info by construction (notifier.py blurple). */
.btn-discord{ background:var(--info); border-color:var(--info); color:var(--on-solid);
              min-height:46px; font-size:var(--fs-body); width:100%; }
.btn-discord:hover:not(.disabled){ filter:brightness(1.08); }
.btn-discord.disabled{ opacity:.45; cursor:not-allowed; }

/* legacy badge state classes -> the semantic five */
.badge.approved,.badge.auto_approved{ background:var(--ok-weak); color:var(--ok-fg); }
.badge.pending{ background:var(--warn-weak); color:var(--warn-fg); }
.badge.rejected{ background:var(--bad-weak); color:var(--bad-fg); }
.badge.held,.badge.blocked_no_approver,.badge.blocked_insufficient_balance{
  background:var(--info-weak); color:var(--info-fg); box-shadow:inset 0 0 0 1px var(--info-line);
}

/* legacy card head: app.css styled `.card h3` as the kicker */
.card > h3{
  font-family:var(--font-data);
  font-size:var(--fs-mono-label);
  font-weight:var(--fw-medium);
  letter-spacing:var(--ls-kicker);
  text-transform:uppercase;
  color:var(--text-2);
  margin-block-end:var(--sp-3);
}
:lang(hy) .card > h3{ font-family:var(--font-text); letter-spacing:.06em; text-transform:none; }
/* app.css's `.card` was padded directly rather than via .card__body */
.card:not(:has(.card__body)):not(:has(.card__head)){ padding:var(--sp-5); }

/* legacy stat block -> .metric */
.stat{ display:flex; align-items:baseline; gap:var(--sp-2); }
.stat .num{
  font-family:var(--font-data);
  font-size:var(--fs-metric);
  font-weight:var(--fw-semi);
  font-variant-numeric:tabular-nums lining-nums;
  line-height:1.05; letter-spacing:-.02em; color:var(--text);
}
.stat .unit{ font-size:var(--fs-sm); color:var(--text-3); }

/* legacy balance bar -> .meter */
.bar{ height:8px; border-radius:var(--r-pill); background:var(--track);
      overflow:hidden; margin-block-start:var(--sp-3); }
.bar > span{ display:block; height:100%;
             background:linear-gradient(90deg,var(--cyan-deep),var(--cyan)); }

/* index.html's `<h2 class="page-title">` -> .page__title */
.page-title{
  font-family:var(--font-display);
  font-size:var(--fs-h2);
  font-weight:var(--fw-semi);
  letter-spacing:var(--ls-tight);
  line-height:var(--lh-tight);
  margin-block-end:var(--sp-1);
}
:lang(hy) .page-title{ letter-spacing:0; }

.rolechips{ display:flex; flex-wrap:wrap; gap:var(--sp-2); margin-block-start:var(--sp-1); }
.panel-pre{ white-space:pre-wrap; font-family:var(--font-data); font-size:var(--fs-xs);
            line-height:var(--lh); max-height:280px; overflow:auto;
            background:var(--code-bg); border-radius:var(--r-chip-lg); padding:var(--sp-3); }

.role-tabs button{
  padding:5px 11px; border:1px solid var(--line); border-radius:var(--r-pill);
  background:transparent; color:var(--text-2);
  font-size:var(--fs-xs); font-weight:var(--fw-semi); cursor:pointer; white-space:nowrap;
}
.role-tabs button:hover{ border-color:var(--line-2); color:var(--text); }
.role-tabs button.active{ background:var(--cyan-weak); border-color:var(--cyan-line); color:var(--link); }

/* legacy rail markup: <nav class="nav"><button><span class=ico><span class=lbl> */
.side-top{ display:flex; align-items:center; gap:var(--sp-2); padding:0 var(--sp-2) var(--sp-4); }
.side-top b{ font-family:var(--font-display); font-weight:var(--fw-bold); }
.side-top em{ font-style:normal; color:var(--text-3); }
.nav{ display:flex; flex-direction:column; gap:2px; padding:0 var(--sp-1); }
.nav button{
  display:grid; grid-template-columns:20px minmax(0,1fr); align-items:center; gap:var(--sp-3);
  width:100%; min-height:38px; padding:var(--sp-2) var(--sp-3);
  border-radius:var(--r-chip-lg); color:var(--text-2);
  font-size:var(--fs-sm); font-weight:var(--fw-medium); text-align:start; cursor:pointer;
  transition:background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.nav button:hover{ background:var(--overlay-1); color:var(--text); }
.nav button.active{ background:var(--cyan-weak); color:var(--text); font-weight:var(--fw-semi); }
.nav .ico{ display:grid; place-items:center; width:20px; }
.side-foot{ margin-block-start:auto; padding:var(--sp-3) var(--sp-2) 0;
            border-block-start:1px solid var(--line);
            font-size:var(--fs-xs); color:var(--text-3); }
.side-foot .who{ color:var(--text); font-weight:var(--fw-semi); font-size:var(--fs-sm); }
.brand{ display:inline-flex; align-items:center; gap:var(--sp-2);
        font-family:var(--font-display); font-weight:var(--fw-bold); }
.brand em{ font-style:normal; color:var(--text-3); font-weight:var(--fw-regular); }
.brand-mark{
  display:grid; place-items:center; width:32px; height:32px; flex:0 0 auto;
  border-radius:var(--r-chip); background:var(--cyan); color:var(--on-accent);
  font-family:var(--font-display); font-weight:var(--fw-bold);
}
