/* Shared design tokens and base controls for every surface: the extension's
 * popup and the full web app in apps/app.
 *
 * This is the nocold.email brand identity v1 (September 2026) expressed as
 * CSS. Two layers, and the order matters:
 *
 *   1. Brand tokens  — ember, ink, frost, glacier, paper, honey, slate, mist.
 *      Fixed hexes. They never change with the colour scheme, because the app
 *      icon, the strike and the chips have to be the same colour in a dark
 *      Gmail as in a light one.
 *   2. Page tokens   — --fg, --bg, --border, and the status families. These
 *      are derived from layer 1 and *do* flip with the colour scheme.
 *
 * The whole identity is one move: the snowflake with the ember strike through
 * it. The name is set plainly beside it, in one colour, and everything else is
 * temperature. Frost is what the classifier finds; ember is what nocold does
 * about it.
 *
 * How the nine brand colours map onto the states this product actually has:
 *
 *   cold   frost / glacier   the verdict, the chip, the Cold Emails label
 *   warm   jade              not cold, kept, brought back — the answers that
 *                            leave your mail alone
 *   flag   honey             not sure, waiting for you
 *   info   slate / mist      newsletter, neutral notes
 *   red    #B42318           errors and destructive actions only
 *
 * Three temperatures, three hues, and ember is not one of them. `flag` used to
 * be ember and `warm` used to be honey, which put a full-saturation ember tint
 * on every "waiting for you" pill and left the product with no colour at all
 * for "we left this alone". Honey moved down to flag, jade took warm, and ember
 * went back to the brand book's rule: the strike, primary buttons, and a switch
 * that is on. Nothing else.
 *
 * This is the palette the Chrome Web Store screenshots are drawn in, so a
 * person who installs from the listing meets the same three colours inside.
 *
 * Fonts are vendored (assets/fonts, copied next to this file by each app's
 * build) rather than linked from Google Fonts: the popup must paint from cache
 * in well under 100ms, and a Chrome Web Store review treats a remote font as a
 * remote resource. Both are single variable files covering the whole weight
 * range, and both are SIL Open Font License 1.1:
 *   Gabarito        display — the wordmark, headlines, the one big number
 *   Instrument Sans UI     — body copy, settings, labels
 */
@font-face {
  font-family: 'Gabarito';
  src: url('assets/fonts/gabarito.woff2') format('woff2');
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('assets/fonts/instrument-sans.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---------- 1. Brand tokens: fixed, never themed ---------- */
  --ember: #FF4F1F;        /* the strike, primary buttons */
  --ember-deep: #C23A10;   /* ember as text on a light fill */
  --ink: #0B1220;          /* the icon's ground, dark surfaces, the deepest plate */
  --ink-text: #0F1A2B;     /* the same ink, one step lighter, for body copy */
  --frost: #CBEBFF;        /* the snowflake on ink */
  --frost-fill: #DDF2FF;   /* the cold chip's fill */
  --glacier: #1D8BD6;      /* the cold verdict */
  --glacier-deep: #0B5E9E; /* cold chip text, for contrast */
  --paper: #FFF8F0;        /* the popup and marketing. Warm on purpose. */
  --honey: #FFB43A;        /* not sure, waiting for you */
  --honey-fill: #FFF1D6;
  --honey-deep: #8A5A00;
  --jade: #2FBF71;         /* kept, brought back, left alone */
  --jade-fill: #D9F5E6;
  --jade-deep: #0B6B42;
  --slate: #5B6B80;        /* secondary text */
  --mist: #E7ECF1;         /* rules, borders, disabled */

  /* ---------- Type ---------- */
  --font: 'Instrument Sans', Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Gabarito', 'Outfit', system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ---------- 2. Page tokens: light ---------- */
  --fg: #0F1A2B;
  --fg-2: #33445C;
  --fg-3: #5B6B80;
  --fg-4: #8496A9;
  --bg: #ffffff;
  --bg-sunken: #F4F8FB;
  --bg-subtle: #F7FAFC;
  --bg-hover: #EEF3F8;
  --border: #E7ECF1;
  --border-strong: #D2DBE4;
  --border-faint: #F0F4F8;
  --overlay: rgba(15, 26, 43, .45);

  /* Cold: the verdict. Frost fill, glacier text — the chip, exactly. */
  --cold: #1D8BD6;
  --cold-fg: #0B5E9E;
  --cold-bg: #DDF2FF;
  --cold-soft: #F2FAFF;
  --cold-border: #CBEBFF;
  --cold-dot: #1D8BD6;
  /* Warm: not cold, kept, brought back. Jade — the answers that leave your
     mail exactly where it was. */
  --warm: #2FBF71;
  --warm-fg: #0B6B42;
  --warm-bg: #D9F5E6;
  --warm-soft: #F1FBF6;
  --warm-border: #A8E6C6;
  --warm-dot: #2FBF71;
  /* Flag: not sure, waiting for you. Honey — the one colour that asks. */
  --flag: #FFB43A;
  --flag-fg: #8A5A00;
  --flag-bg: #FFF1D6;
  --flag-soft: #FFFAF0;
  --flag-border: #FFDFA3;
  --flag-dot: #FFB43A;
  /* Info: newsletter, brought back, neutral notes. */
  --info: #5B6B80;
  --info-fg: #445468;
  --info-bg: #E7ECF1;
  --info-soft: #F2F5F8;
  --info-border: #D2DBE4;
  /* Red is reserved for the two things that really are red — an error, and a
     destructive action. Deliberately darker than ember so the two never read
     as the same colour on one screen. */
  --red: #B42318;
  --red-fg: #8F1D13;
  --red-bg: #FBE3E0;
  --red-soft: #FEF4F2;
  --red-border: #F3BDB6;

  /* Primary action. The brand book is explicit: primary buttons are ember. */
  --solid: #FF4F1F;
  --solid-hover: #E8410F;
  --solid-fg: #ffffff;
  /* A surface that inverts the page — the toast. Ink under light, paper under
     dark, so it always reads as "on top of" rather than "part of". */
  --inverse: #0F1A2B;
  --inverse-fg: #FFF8F0;

  --r-chip: 6px;
  --r-btn: 7px;
  --r-input: 9px;
  --r-card: 16px;
  --shadow-sm: 0 1px 2px rgba(15, 26, 43, .06);
  --shadow-md: 0 4px 14px rgba(15, 26, 43, .10);
  --shadow-lg: 0 12px 34px rgba(15, 26, 43, .18);
  --ring: 0 0 0 3px rgba(255, 79, 31, .22);
  /* The logo tile's edge. Ink on white needs none, so this is a no-op that the
     dark theme replaces; it is a variable rather than a rule so surfaces that
     give the tile their own shadow can compose the two. */
  --logo-ring: 0 0 #0000;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* The dark plate is the one the store screenshots are drawn on: a near-black
       ink page, panels one step up from it, and a single hairline. */
    --fg: #F2F5F8;
    --fg-2: #C3CDD9;
    --fg-3: #8FA0B5;
    --fg-4: #6F7E92;
    --bg: #111A2A;
    --bg-sunken: #0A111C;
    --bg-subtle: #182434;
    --bg-hover: #1D2A3E;
    --border: #24344A;
    --border-strong: #35455C;
    --border-faint: #1A2537;
    --overlay: rgba(4, 8, 14, .62);

    /* Tints, not solids. A flat fill has to be mixed for one background and is
       wrong on the next one up; a translucent tint of the same hue lands right
       on the page, on a panel and on a hovered row alike. */
    --cold: #2D9BE6;
    --cold-fg: #8FCDF5;
    --cold-bg: rgba(45, 155, 230, .20);
    --cold-soft: rgba(45, 155, 230, .14);
    --cold-border: rgba(45, 155, 230, .38);
    --cold-dot: #2D9BE6;
    --warm: #2FBF71;
    --warm-fg: #68DFA9;
    --warm-bg: rgba(47, 191, 113, .18);
    --warm-soft: rgba(47, 191, 113, .14);
    --warm-border: rgba(47, 191, 113, .38);
    --warm-dot: #2FBF71;
    --flag: #FFB43A;
    --flag-fg: #FFC978;
    --flag-bg: rgba(255, 180, 58, .18);
    --flag-soft: rgba(255, 180, 58, .14);
    --flag-border: rgba(255, 180, 58, .38);
    --flag-dot: #FFB43A;
    --info: #8FA0B5;
    --info-fg: #C3CDD9;
    --info-bg: rgba(143, 160, 181, .16);
    --info-soft: rgba(143, 160, 181, .08);
    --info-border: #35455C;
    --red: #F0705E;
    --red-fg: #F79484;
    --red-bg: #3E1611;
    --red-soft: #2C100C;
    --red-border: #6B241B;

    --solid: #FF5F33;
    --solid-hover: #FF7550;
    --solid-fg: #ffffff;
    --inverse: #F3EEE6;
    --inverse-fg: #0F1A2B;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, .5);
    --shadow-lg: 0 12px 34px rgba(0, 0, 0, .6);
    --ring: 0 0 0 3px rgba(255, 95, 51, .3);
    /* An ink tile on an ink page has no edge at all. A frost hairline gives it
       one without touching the mark's own fixed colours. */
    --logo-ring: inset 0 0 0 1px rgba(203, 235, 255, .18);
  }
  select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239AA7B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
}

* { box-sizing: border-box; }

/* An author `display` rule (.row, .banner, …) outranks the UA sheet's
   [hidden] { display: none }, so el.hidden alone would set the attribute and
   keep painting. Declared once, here, for every surface. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'tnum' 1;
}

/* Gabarito, pulled tight. Instrument Sans stays out of its way: regular for
   reading, semibold for labels, never bold. */
h1, h2, h3 { margin: 0; font-family: var(--font-display); font-weight: 700; letter-spacing: -.02em; }

a { color: inherit; }

.num { font-family: var(--font-display); font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.muted { color: var(--fg-3); }
.faint { color: var(--fg-4); }
.truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Wordmark ---------- */
/* The logo is the full domain — nocold.email — set as one word in one colour.
   Nothing in the name is struck through and no part of it is tinted: the
   strike is the mark's, drawn once in the glyph beside the name, and the
   colour that used to separate `cold` from `no` was doing the mark's job a
   second time on the one word a reader has to decode.
   Markup: <span class="wm"><span class="no">no</span><span class="cold">cold</span><span class="tld">.email</span></span>
   The three spans stay — they are the seam a surface would need if the name
   ever has to be tinted again — but all three simply inherit --wm-ink. The
   name is never shortened to "nocold": wordmark() in index.js always writes
   all three spans, so there is one place to get this right and it is already
   right.
 *
 * One colour is also the readable answer. The wordmark gets used at 17-21px,
 * not at the hero sizes it was drawn at, and ink on paper is about 16:1 there
 * — against the 6.3:1 glacier-deep managed on `cold` and the 5.0:1 slate gave
 * `.email`. `.email` keeps only its lighter weight, so the domain still reads
 * as a domain without a second colour doing the work. */
.wm {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -.045em;
  line-height: 1;
  white-space: nowrap;
  display: inline-block;
  --wm-ink: var(--fg);
  color: var(--wm-ink);
}
.wm .tld { font-weight: 500; letter-spacing: -.02em; }
/* Reversed, for ink plates and photography. */
.wm.rev { --wm-ink: var(--paper); }
/* Print and mono favicons: take whatever colour the surface is already in. */
.wm.mono { --wm-ink: currentColor; }

/* The primary lockup: mark, then wordmark. Clear space on all sides equal to
   the height of the letter o — roughly a third of the mark. */
.lockup { display: inline-flex; align-items: center; gap: .3em; }
.lockup .wm { font-size: 1em; }

/* ---------- Chips ---------- */
/* 20px tall, 6px radius, 12px semibold, 4px between glyph and word — the same
   chip the extension draws next to a Gmail subject (see the content script's
   own stylesheet, which cannot use these tokens). Cold is the default state;
   flag is the band we are not sure about, and warm only appears when someone
   marks a message themselves. */
.nc-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 20px;
  padding: 0 7px 0 5px;
  border-radius: var(--r-chip);
  font-weight: 600;
  font-size: 12px;
  line-height: 1;
  white-space: nowrap;
  flex: none;
}
.nc-chip svg { width: 12px; height: 12px; flex: none; }
.nc-chip.cold { background: var(--cold-bg); color: var(--cold-fg); }
.nc-chip.flag { background: var(--flag-bg); color: var(--flag-fg); }
.nc-chip.warm { background: var(--warm-bg); color: var(--warm-fg); }
.nc-chip.big { height: 28px; font-size: 15px; padding: 0 10px 0 7px; border-radius: 8px; }
.nc-chip.big svg { width: 16px; height: 16px; }

/* ---------- Evidence list ---------- */
/* Why a message was called what it was called: an arrow, then one short line.
   Up is a reason it looks cold and takes the cold hue; down is a reason it does
   not and takes the warm one. Used by the Gmail hover card, the dashboard's Why
   column and the expanded row, so the same evidence reads the same everywhere. */
.ev { display: flex; flex-direction: column; gap: 3px; font-size: 12px; line-height: 1.45; }
.ev i { display: flex; align-items: flex-start; gap: 7px; font-style: normal; min-width: 0; }
.ev i::before { font-style: normal; font-weight: 700; line-height: inherit; flex: none; }
.ev i.up::before { content: '\2191'; color: var(--cold-fg); }
.ev i.down::before { content: '\2193'; color: var(--warm-fg); }
.ev i.flat::before { content: '\00B7'; color: var(--fg-4); }
.ev i.up { color: var(--fg-2); }
.ev i.down { color: var(--fg-2); }
.ev i.flat { color: var(--fg-3); }

/* ---------- Cold score ---------- */
/* A track and the number, and the number is the loudest thing in the cell: it
   is the one figure on the screen a person is entitled to argue with. */
.cscore { display: flex; align-items: center; gap: 10px; }
.cscore .track { flex: 1; min-width: 28px; height: 6px; border-radius: 999px; background: var(--border); overflow: hidden; }
.cscore .track i { display: block; height: 100%; border-radius: 999px; background: var(--cold); transition: width .3s ease; }
.cscore .track i.flag { background: var(--flag); }
.cscore .track i.warm { background: var(--warm); }
.cscore .track i.grey { background: var(--fg-4); }
.cscore b { font-family: var(--font-display); font-weight: 800; font-size: 16px; letter-spacing: -.02em; font-variant-numeric: tabular-nums; min-width: 26px; text-align: right; color: var(--cold-fg); }
.cscore b.flag { color: var(--flag-fg); }
.cscore b.warm { color: var(--warm-fg); }
.cscore b.grey { color: var(--fg-3); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 36px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-input);
  background: var(--bg);
  color: var(--fg-2);
  font: 600 13px var(--font);
  cursor: pointer;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, opacity .12s ease;
}
.btn:hover:not(:disabled) { background: var(--bg-subtle); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn:disabled { opacity: .5; cursor: default; }
.btn.primary { border-color: transparent; background: var(--solid); color: var(--solid-fg); padding: 0 14px; }
.btn.primary:hover:not(:disabled) { background: var(--solid-hover); }
.btn.sm { height: 30px; padding: 0 10px; font-size: 12px; border-radius: var(--r-btn); }
.btn.xs { height: 26px; padding: 0 10px; font-size: 11.5px; border-radius: var(--r-btn); }
.btn.lg { height: 44px; padding: 0 20px; font-size: 14px; }
.btn.block { width: 100%; }
.btn.keep { border-color: var(--warm-border); background: var(--warm-soft); color: var(--warm-fg); }
.btn.keep:hover:not(:disabled) { background: var(--warm-bg); }
.btn.cold { border-color: var(--cold-border); background: var(--cold-soft); color: var(--cold-fg); }
.btn.cold:hover:not(:disabled) { background: var(--cold-bg); }
.btn.danger { border-color: var(--red-border); background: var(--bg); color: var(--red); }
.btn.danger:hover:not(:disabled) { background: var(--red-soft); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover:not(:disabled) { background: var(--bg-hover); }
.btn.icon { width: 36px; padding: 0; }
.btn.sm.icon { width: 30px; }
/* Official Google sign-in button: white, full-contrast label, subtle lift. */
.btn.google { color: var(--fg); background: var(--bg); box-shadow: var(--shadow-sm); }

/* ---------- Inline notes ---------- */
/* Used by the popup and the dashboard for paused / test-mode / last-error. */
.note {
  padding: 8px 10px;
  border: 1px solid var(--info-border);
  border-radius: var(--r-input);
  background: var(--info-soft);
  color: var(--info-fg);
  font-size: 11.5px;
  line-height: 1.45;
}
.note.bad { border-color: var(--red-border); background: var(--red-soft); color: var(--red); word-break: break-word; }

.spin { animation: cef-spin .8s linear infinite; }
@keyframes cef-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spin { animation-duration: 2.4s; } }

/* ---------- Form controls ---------- */
input[type=text], input[type=number], input[type=password], input[type=search], select, textarea {
  font: 400 13px var(--font);
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-input);
  background: var(--bg);
  color: var(--fg);
}
textarea { height: auto; padding: 8px 10px; font-family: var(--font-mono); font-size: 12px; line-height: 1.5; resize: vertical; }
/* Native select chrome does not match anything else on the page, so draw our
   own chevron and keep the control identical to a secondary button. */
select {
  appearance: none;
  padding: 0 30px 0 10px;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235B6B80' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
select:hover { background-color: var(--bg-subtle); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--ember); box-shadow: var(--ring); }
input::placeholder, textarea::placeholder { color: var(--fg-4); }

/* Switch: a 36x20 pill, ember when on — the one warm thing on the panel.
   `.lg` is the 44x25 the brand book draws, for the four switches on the first
   settings panel that say what the product does at all. */
.switch { position: relative; width: 36px; height: 20px; flex: none; border: 0; padding: 0; border-radius: 999px; background: var(--border-strong); cursor: pointer; transition: background .15s ease; }
.switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--shadow-sm); transition: transform .15s ease; }
.switch[aria-checked=true] { background: var(--ember); }
.switch[aria-checked=true]::after { transform: translateX(16px); background: #fff; }
.switch:focus-visible { outline: none; box-shadow: var(--ring); }
.switch.lg { width: 44px; height: 25px; }
.switch.lg::after { top: 3px; left: 3px; width: 19px; height: 19px; }
.switch.lg[aria-checked=true]::after { transform: translateX(19px); }

/* Checkbox drawn as a 16px square so it matches the design in both themes. */
.check { position: relative; width: 16px; height: 16px; flex: none; border: 1.5px solid var(--border-strong); border-radius: 4px; background: var(--bg); padding: 0; cursor: pointer; }
.check[aria-checked=true] { border-color: var(--ember); background: var(--ember); }
.check[aria-checked=true]::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 1px;
  width: 4px;
  height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.check:focus-visible { outline: none; box-shadow: var(--ring); }

/* ---------- Pills and badges ---------- */
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: var(--r-chip); font-size: 10.5px; font-weight: 600; }
.pill.warm { background: var(--warm-bg); color: var(--warm-fg); }
.pill.flag { background: var(--flag-bg); color: var(--flag-fg); }
.pill.cold { background: var(--cold-bg); color: var(--cold-fg); }
.pill.info { background: var(--info-bg); color: var(--info-fg); }
.pill.red { background: var(--red-bg); color: var(--red-fg); }
.pill.grey { background: var(--bg-sunken); color: var(--fg-3); }

.dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.dot.warm { background: var(--warm-dot); }
.dot.flag { background: var(--flag-dot); }
.dot.cold { background: var(--cold-dot); }
.dot.grey { background: var(--fg-4); }

/* Brand mark: the app icon. An ink rounded square, a frost snowflake, and an
   ember bar struck through it — the same geometry Chrome shows in the toolbar.
   Sizes come from the caller (logoMark in index.js, or the surface's own CSS);
   the colours are brand tokens, so the tile looks identical in both themes. */
.logo { display: flex; align-items: center; justify-content: center; flex: none; background: var(--ink); color: var(--frost); overflow: hidden; box-shadow: var(--logo-ring); }

/* Sender initials. */
.avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border-radius: 50%;
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  color: var(--fg-3);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.avatar.hot { background: var(--cold-bg); border-color: var(--cold-border); color: var(--cold-fg); }

/* ---------- Toast ---------- */
.toasts { position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%); display: flex; flex-direction: column; gap: 8px; z-index: 60; pointer-events: none; }
.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px 10px 14px;
  border-radius: 12px;
  background: var(--inverse);
  color: var(--inverse-fg);
  font-size: 13px;
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: cef-rise .18s ease-out;
}
.toast.bad { background: var(--red); color: #fff; }
.toast button { border: 0; background: transparent; color: inherit; font: 600 13px var(--font); cursor: pointer; padding: 2px 4px; opacity: .85; }
.toast button:hover { opacity: 1; }
@keyframes cef-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ---------- Scrollbars ---------- */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border: 3px solid transparent; background-clip: content-box; border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--fg-4); background-clip: content-box; }
