/* app-specific styles
   ─────────────────────────────────────────────────────────────────────────
   Design system lifted from sh-development-v4 (github.com/shumilovsergey/
   sh-development-v4, css/styles.css): flat black ground with a soft top glow,
   solid (non-glass) cards, Apple-ish sans for chrome + mono for app names.

   menu has ONE layout. There is no desktop variant — every viewport renders
   the phone layout, sized against an iPhone 16 (393 × 852 CSS px) and simply
   centered in whatever space is available. No width media queries below. */

/* ── TOKENS ───────────────────────────────────────────────────────────────
   shell.css owns these names; app.css retints them (shell.css is read-only).
   Everything below consumes variables — no raw colors in rules. */

:root {
  /* shell.css palette, repointed at the v4 dark theme */
  --bg:            #000000;  /* v4 --bg        */
  --card:          #131315;  /* v4 --bg-soft   */
  --border:        #1c1c1f;  /* v4 --line-soft */
  --border-active: #2b2b2e;  /* v4 --line      */
  --text:          #a1a1a6;  /* v4 --ink-soft  */
  --text-dim:      #6e6e73;  /* v4 --ink-faint */
  --accent:        #f5f5f7;  /* v4 --ink       */
  --neon:          #ffffff;

  /* v4 tokens shell.css has no equivalent for */
  --sunk:        #0a0a0b;
  --read:        #cbcbd0;
  --accent-bg:   rgba(255, 255, 255, .08);
  --accent-line: rgba(255, 255, 255, .22);
  --tile-ring:   rgba(255, 255, 255, .34);

  --glow:
    radial-gradient(30rem 20rem at 50% -2%, rgba(255, 255, 255, .13), transparent 70%),
    radial-gradient(64rem 40rem at 50% -8%, rgba(255, 255, 255, .09), transparent 66%);

  --radius: 18px;
  --head-h: 5.8rem;  /* wordmark block incl. the gap under it */

  /* The profile circle's diameter must equal the tab pill's height, so the
     pill's height is stated rather than left to the tab's line box. Change
     --tab-h or --nav-pad and the circle follows. */
  --tab-h:   2.6rem;
  --nav-pad: .4rem;
  --nav-h:   calc(var(--tab-h) + 2 * var(--nav-pad) + 2px);  /* +2px: borders */
  --wrap:   26rem;  /* the single column width — phone-sized on every screen */
  --shadow: 0 1px 1px rgba(0, 0, 0, .5), 0 18px 48px -28px rgba(0, 0, 0, .9);
  --ease:   cubic-bezier(.32, .72, 0, 1);

  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text',
          'Helvetica Neue', 'Segoe UI', Inter, Roboto, Arial, sans-serif;

  /* traffic-light palette — the dots are gone from the markup, but app.js
     still classes cards and the status popup still uses these. */
  --ok:   #4ade80;
  --warn: #fbbf24;
  --bad:  #f87171;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── GROUND ───────────────────────────────────────────────────────────────
   Flat black + the v4 top glow, replacing the blurred photo backdrop. */

html { background: var(--bg); color-scheme: dark; }

body {
  background: var(--bg);
  color: var(--accent);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.5;
  letter-spacing: -.01em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--glow);
}

:focus-visible { outline: 1.5px solid var(--accent); outline-offset: 3px; border-radius: 6px; }

/* ── NAVBAR ───────────────────────────────────────────────────────────────
   shell.css lays the bar out as a space-between row (tabs left, profile
   right). Here the pill and the profile circle instead travel together as one
   centered group at the top, v4-style — two separate floating capsules with a
   gap between them, so the circle reads as its own control rather than a
   button glued onto the bar. */

.navbar {
  position: fixed;
  top: 1.4rem;
  left: 50%;
  z-index: 20;
  transform: translateX(-50%);
  justify-content: center;
  align-items: center;
  gap: .55rem;
  max-width: calc(100% - 1.5rem);
  padding: 0;
}

.nav-tabs {
  gap: .15rem;
  padding: var(--nav-pad) .45rem;
  background: color-mix(in srgb, var(--card) 72%, transparent);
  border: 1px solid var(--border-active);
  border-radius: 999px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
}

.tab {
  min-width: 0;
  height: var(--tab-h);
  padding: 0 1.2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-family: var(--sans);
  font-size: .95rem;
  font-weight: 450;
  letter-spacing: -.005em;
  color: var(--text);
  transition: background .25s var(--ease), color .25s var(--ease);
}

.tab:hover { color: var(--accent); background: var(--accent-bg); }

.tab.active {
  color: var(--accent);
  font-weight: 500;
  background: var(--accent-bg);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}

/* ── CONTENT SHELL ────────────────────────────────────────────────────────
   Top padding clears the floating pill (which is fixed, so it is out of flow);
   the block then centers in what is left. Only the DIFFERENCE between the two
   paddings matters: it shifts the block by half of that difference, which is
   how the first card is held at ~278px from the top.

   Careful: both panels share one grid cell, so the cell is as tall as the
   TALLER of them — currently the info card, not the app stack. Change the
   info card's height (a paragraph, the header, a contact row) and the apps
   tab moves too; re-tune the bottom padding here if it does. */

.app-content {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 5.5rem 1.25rem .35rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  align-items: stretch;   /* shell.css sets center here; both panels must fill
                             the cell, or the shorter one re-centres and the
                             info card stops lining up with card #1 */
}

/* Both panels occupy the SAME grid cell and stay in flow (hidden with
   visibility, not display). The cell is therefore as tall as the taller panel
   on both tabs, so switching tabs never shifts the page vertically — and since
   grid items align to the cell's top, #panel-info's --head-h offset lands its
   card on exactly the same line as the first app card. */
.tab-panel {
  grid-area: 1 / 1;
  width: 100%;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

.tab-panel.active {
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

/* offset the info text by the header's height so it starts level with card #1 */
#panel-info { padding-top: var(--head-h); }

/* ── APP LIST ─────────────────────────────────────────────────────────────
   Four free-standing cards with gaps, not one panel split by hairlines. */

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

/* ── APPS HEADER ──────────────────────────────────────────────────────────
   Wordmark above the stack. It sits inside .apps-wrap, so it centres together
   with the cards rather than floating on its own. Mono ties it to the app
   names and to the login screen's MENU logo; the nav pill stays sans. */

.apps-head {
  height: var(--head-h);   /* fixed: #panel-info offsets by the same variable */
  text-align: center;
}

.apps-title {
  margin: 0;
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.15;
  color: var(--accent);
}

.apps-sub {
  margin: .55rem 0 0;
  font-size: .92rem;
  line-height: 1.4;
  color: var(--text-dim);
}

.app-grid {
  display: grid;
  gap: .9rem;
  align-items: start;
}

.app-card {
  position: relative;
  height: 5.25rem;
  padding: 1.1rem 1.35rem;
  display: flex;
  align-items: center;
  gap: .95rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: background .18s ease, border-color .18s ease, opacity .18s ease;
}

.app-card:not(.blocked):hover { background: var(--sunk); border-color: var(--border-active); }

/* the full-row overlay link */
.app-open { position: absolute; inset: 0; z-index: 1; }
.app-open:focus-visible { outline-offset: -4px; }

/* a card app.js could not reach dims; clicking it raises the status popup */
.app-card.blocked .app-icon,
.app-card.blocked .app-name { opacity: .45; }
/* re-enable together with PRE_REDIRECT_CHECK in app.js — while the gate is
   off a blocked card still opens, so this cursor would be misleading:
.app-card.blocked .app-open { cursor: not-allowed; } */

/* ── icon tile ────────────────────────────────────────────────────────── */

.app-icon {
  flex: none;
  width: 2.9rem;
  height: 2.9rem;
  padding: 0;
  display: grid;
  place-items: center;
  background: var(--card);
  border-radius: .725rem;
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 1.1rem;
  font-weight: 600;
  text-transform: uppercase;
  overflow: hidden;
}

/* No ring here: every icon SVG already paints its own inset frame at exactly
   --tile-ring's value (stroke="#ffffff" stroke-opacity=".34"), so a CSS border
   on top of it reads as a double frame. The letter fallback has no SVG, so it
   gets the ring instead. */
.app-icon:not(:has(img)) {
  background: var(--sunk);
  box-shadow: inset 0 0 0 1px var(--tile-ring);
}

/* the SVG is the tile: it fills edge to edge, and .app-icon's .725rem radius
   matches the artwork's own rx so the clip lines up instead of shaving it */
.app-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── status dot ────────────────────────────────────────────────────────
   Driven entirely by the classes app.js already puts on .app-card
   (checking / online / partial / offline). It sits just left of the info
   section, so the card reads: icon — name — state — info. */

.app-card .dot {
  flex: none;
  width: .5rem;
  height: .5rem;
  margin-right: .95rem;
  border-radius: 50%;
  background: var(--text-dim);
}

.app-card.checking .dot { animation: dot-pulse 1.1s ease-in-out infinite; }
.app-card.online   .dot { background: var(--ok);   box-shadow: 0 0 .5rem color-mix(in srgb, var(--ok)   65%, transparent); }
.app-card.partial  .dot { background: var(--warn); box-shadow: 0 0 .5rem color-mix(in srgb, var(--warn) 65%, transparent); }
.app-card.offline  .dot { background: var(--bad);  box-shadow: 0 0 .5rem color-mix(in srgb, var(--bad)  65%, transparent); }

@keyframes dot-pulse {
  0%, 100% { opacity: .3; }
  50%      { opacity: 1; }
}

/* Hidden for now — delete this one rule to bring the indicators back. The
   markup and every state class above stay put, and app.js keeps probing
   /status on load. Card height is fixed, so nothing shifts vertically. */
.app-card .dot { display: none; }

/* ── info section ──────────────────────────────────────────────────────
   A full-height strip down the card's right edge, split off by one hairline
   (per card.png). Negative margins let it bleed through .app-card's padding
   to the very edge; the card's overflow:hidden clips it to the corner radius.
   z-index puts it above .app-open, so a tap here opens the popup instead of
   the app. */

.app-info-btn {
  position: relative;
  z-index: 2;
  flex: none;
  align-self: stretch;
  width: 3.9rem;
  margin: -1.1rem -1.35rem -1.1rem 0;
  display: grid;
  place-items: center;
  background: var(--border-active);   /* the old divider colour, now the fill —
                                         the strip's own edge is the divider */
  color: var(--text);
  font-family: var(--mono);
  font-size: 1.05rem;
  font-style: italic;
  line-height: 1;
  transition: background .18s ease, color .18s ease;
}

.app-info-btn:hover {
  background: color-mix(in srgb, var(--border-active) 86%, var(--neon));
  color: var(--accent);
}

/* ── refresh ───────────────────────────────────────────────────────────
   Circle with the two-arrow glyph, centred under the stack. app.js toggles
   .spinning on it for the duration of a check. */

.app-refresh {
  margin: 1.4rem auto 0;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text);
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.app-refresh:hover { background: var(--sunk); border-color: var(--border-active); color: var(--accent); }

.app-refresh svg { width: 1.15rem; height: 1.15rem; }

.app-refresh.spinning { color: var(--text-dim); pointer-events: none; }
.app-refresh.spinning svg { animation: spin .8s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

/* Hidden for now — delete this one rule to bring the button back. The markup,
   the app.js listener and the .spinning styles above all stay put; statuses
   still refresh on page load via checkStatus(). */
.app-refresh { display: none; }

/* ── name ─────────────────────────────────────────────────────────────── */

.app-name {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: -.015em;
  line-height: 1.3;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── CARD HEADER ──────────────────────────────────────────────────────────
   One entry point, used by the popup and the info card alike: a mark, a title
   and a hairline that closes the header off from the body. Before this the
   info card began mid-sentence and the popup's lead ran straight into its
   list, so neither had anywhere for the eye to land first. */

.card-head {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding-bottom: .85rem;
  border-bottom: 1px solid var(--border-active);
}

.card-head-mark {
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: .45rem;   /* matches the tiles' own rx at this size */
}

/* ── INFO TAB ─────────────────────────────────────────────────────────── */

.info-card {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
  padding: 1.75rem 1.5rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: .95rem;
  line-height: 1.65;
}

.info-title {
  margin: 0;
  font-family: var(--mono);
  font-size: 1.05rem;
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--accent);
}

.info-card strong { color: var(--accent); font-weight: 600; }
.info-card .info-foot { color: var(--text-dim); font-size: .85rem; }

.info-card p a {
  color: var(--read);
  text-decoration: none;
  border-bottom: 1px solid var(--border-active);
}

.info-card p a:hover { color: var(--accent); border-bottom-color: var(--text-dim); }

.info-links {
  display: flex;
  flex-direction: column;
  gap: .7rem;
}

/* Left-aligned, not centred: the paragraphs above establish a left reading
   edge and centred pills broke it. The trailing glyph also tells the two
   apart — one copies to the clipboard, the other opens a new tab, and until
   now they looked identical. */
.info-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  width: 100%;
  padding: .8rem 1rem;
  background: var(--sunk);
  border: 1px solid var(--border);
  border-radius: .75rem;
  color: var(--text);
  font-family: var(--mono);
  font-size: .85rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.info-link-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.info-link-icon {
  flex: none;
  width: .9rem;
  height: .9rem;
  color: var(--text-dim);
  transition: color .18s ease;
}

.info-link:hover .info-link-icon { color: var(--accent); }

.info-link:hover { background: var(--accent-bg); border-color: var(--border-active); color: var(--accent); }

/* ── LOGIN SCREEN ─────────────────────────────────────────────────────── */

.login-screen { padding: 1.5rem 1.25rem 1.75rem; position: relative; z-index: 1; }
.login-screen::before { content: none; }  /* the photo scrim is obsolete */

.login-card {
  max-width: var(--wrap);
  padding: 2.75rem 2rem 2.25rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.login-logo {
  font-family: var(--mono);
  font-size: 1.6rem;
  letter-spacing: .16em;
  color: var(--accent);
  text-shadow: none;
}

.login-domain {
  font-family: var(--mono);
  font-size: .8rem;
  color: var(--text-dim);
}

.login-domain:hover { color: var(--text); }

.login-btn {
  padding: .9rem;
  background: var(--sunk);
  border: 1px solid var(--border-active);
  border-radius: .75rem;
  color: var(--accent);
  font-family: var(--sans);
  font-size: .95rem;
}

.login-btn:hover { background: var(--accent-bg); border-color: var(--accent-line); }

.app-about {
  max-width: var(--wrap);
  font-size: .9rem;
  line-height: 1.7;
  color: var(--text-dim);
  text-shadow: none;
}

.login-divider { max-width: var(--wrap); }
.login-divider::before,
.login-divider::after { background: var(--border); }
.login-divider-dot { border-color: var(--border-active); }

/* ── MODALS ───────────────────────────────────────────────────────────────
   The info button is gone from the markup, but #appModal and #statusModal
   stay wired in app.js — the status popup still fires on a blocked card. */

.app-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(0, 0, 0, .62);
  backdrop-filter: blur(11px);
  -webkit-backdrop-filter: blur(11px);
}

.app-modal-backdrop.open { display: flex; }

.app-modal {
  position: relative;
  width: 100%;
  max-width: var(--wrap);
  padding: 1.6rem 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  background: var(--card);
  border: 1px solid var(--border-active);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.app-modal-name { min-width: 0; padding-right: 2.2rem; color: var(--accent); font-family: var(--mono); font-size: 1.05rem; font-weight: 500; letter-spacing: -.02em; }
.app-modal-desc { color: var(--read); font-size: .95rem; line-height: 1.6; }

.app-modal-features {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .7rem;
}

.app-modal-features li {
  position: relative;
  padding-left: 1.25rem;
  color: var(--text);
  font-size: .86rem;
  line-height: 1.55;
}

.app-modal-features li::before {
  content: '';
  position: absolute;
  left: .2rem;
  top: .55rem;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.app-modal-x {
  position: absolute;
  top: .7rem;
  right: .7rem;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  background: var(--sunk);
  border: 1px solid var(--border);
  border-radius: 50%;
  color: var(--text-dim);
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.app-modal-x svg {
  display: block;      /* no baseline gap — the glyph version sat high */
  width: .72rem;
  height: .72rem;
}

.app-modal-x:hover { background: var(--accent-bg); border-color: var(--border-active); color: var(--accent); }

.app-modal-close {
  align-self: flex-end;
  padding: .55rem 1.1rem;
  background: var(--sunk);
  border: 1px solid var(--border);
  border-radius: .65rem;
  color: var(--text);
  font-size: .85rem;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.app-modal-close:hover { background: var(--accent-bg); border-color: var(--border-active); color: var(--accent); }

.status-modal.warn { border-color: color-mix(in srgb, var(--warn) 50%, transparent); }
.status-modal.bad  { border-color: color-mix(in srgb, var(--bad)  50%, transparent); }
.status-modal.warn .app-modal-name { color: var(--warn); }
.status-modal.bad  .app-modal-name { color: var(--bad); }

/* ── TOAST ────────────────────────────────────────────────────────────── */

.app-toast {
  position: fixed;
  left: 50%;
  bottom: 1.75rem;
  transform: translateX(-50%) translateY(12px);
  z-index: 400;
  max-width: calc(100% - 2.5rem);
  padding: .75rem 1.25rem;
  background: var(--card);
  border: 1px solid var(--border-active);
  border-radius: .75rem;
  box-shadow: var(--shadow);
  color: var(--accent);
  font-size: .85rem;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s, transform .2s;
}

.app-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── ERROR BANNER ─────────────────────────────────────────────────────── */

.error-banner { z-index: 500; font-family: var(--mono); }

/* ── PROFILE CIRCLE + POPOVER ─────────────────────────────────────────────
   The circle is the pill's twin: same fill, same border, same blur, same
   shadow — only round, and exactly as tall as the pill (--nav-h). Sitting a
   gap away from the pill, it reads as a second capsule rather than a tab. */

.profile-area { flex: none; }

.profile-btn {
  width:  var(--nav-h);
  height: var(--nav-h);
  background: color-mix(in srgb, var(--card) 72%, transparent);
  border: 1px solid var(--border-active);
  box-shadow: var(--shadow);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  color: var(--text);
  font-family: var(--sans);
  font-size: .95rem;
  font-weight: 500;
  letter-spacing: -.005em;
  text-shadow: none;
  transition: background .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease), transform .2s var(--ease);
}

/* shell.css pairs :hover with .open in one rule and puts a near-white border
   on both, so every state below has to restate border-color to win. */
.profile-btn:hover {
  color: var(--accent);
  border-color: var(--accent-line);
  background: var(--accent-bg);
}

.profile-btn:active { transform: scale(.94); }

.profile-btn.open {
  color: var(--accent);
  border-color: var(--accent-line);
  background: var(--accent-bg);
  box-shadow: var(--shadow), inset 0 0 0 1px var(--accent-line);
}

.profile-popover {
  top: calc(100% + .55rem);
  width: 15rem;
  padding: .5rem;
  gap: .5rem;
  background: var(--card);
  border-color: var(--border-active);
  border-radius: 16px;
  box-shadow: var(--shadow);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transform-origin: top right;
}

/* shell.js swaps display none/flex, so the reveal is an animation on the
   .open state rather than a transition. */
.profile-popover.open { animation: pi-pop .22s var(--ease) both; }

@keyframes pi-pop {
  from { opacity: 0; transform: translateY(-.4rem) scale(.94); }
  to   { opacity: 1; transform: none; }
}

.pi-info { padding: .4rem .6rem .15rem; gap: .15rem; }
.pi-name { color: var(--accent); font-size: .95rem; }
.pi-label, .pi-sub { color: var(--text-dim); }
.pi-label { font-size: .68rem; }
.pi-sub { font-size: .75rem; }

.pi-list {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}

.pi-list .pi-action {
  border: none;
  border-radius: 0;
  padding: .7rem .9rem;
  font-size: .85rem;
  color: var(--text);
  background: var(--sunk);
}

.pi-list .pi-action + .pi-action { border-top: 1px solid var(--border); }
.pi-list .pi-action:hover { background: var(--accent-bg); color: var(--accent); }

.pi-list .pi-logout { color: var(--bad); background: color-mix(in srgb, var(--bad) 8%, var(--sunk)); }
.pi-list .pi-logout:hover { color: var(--bad); background: color-mix(in srgb, var(--bad) 18%, var(--sunk)); }
