/*
   ═══════════════════════════════════════════════════════════════════════════
   GENERATED COPY — DO NOT EDIT. Source: <extension repo>/Pinako/tree-ui.css
   Regenerate with: node "Pinako Pro/_build/sync-shared.mjs"
   (see that script's header for the shared-source rules)
   ═══════════════════════════════════════════════════════════════════════════
*/

/*
 * tree-ui.css — the tab-world BASE PRIMITIVES every tree surface composes onto.
 *
 * Cut VERBATIM out of pinako.html's <style> block by U6 chunk 4 (2026-09-23; the block's
 * 6-space indent removed, nothing else changed; since then the row-hover rules gained a
 * zero-specificity "not while dragging" guard, see "Hover state for flat rows"): the host-contract primitives that
 * session-ui.css's preamble lists (.flat-row, .flat-row-container, .row-content, .tree-row,
 * .row-title, .btn-group, .custom-tooltip + .tt-multiline, .menu-item, .general-btn,
 * .library-tab, .library-tabs-wrapper, .toolbar-btn, .loader-spinner, .box-btn,
 * .btn-row-even) + .menu-scroll, the :root and body.light-mode theme tokens, the universal
 * box-sizing rule, the global ::-webkit-scrollbar dress, and the two keyframes those rules
 * animate. Every rule whose selector list TOUCHES one of those came along whole, in source
 * order, so comma lists carrying page selectors ride here too.
 *
 * ONE FILE, THREE SURFACES (scripts/shared-ui-manifest.json, dist: ships):
 *   popup   pinako.html links it LAST before its <style> block (after ui-primitives.css,
 *           ai-settings-ui.css and media-viewer.css, which the moved rules already
 *           followed), so every page rule of equal specificity still wins by source order
 *   portal  synced to portal/css/tree-ui.css; linked just before css/pinako.css (the page
 *           residue) and portal.css, whose top block holds the portal's own deltas
 *   S17 app scripts/build-mcp-app.js inlines it verbatim (was a selector extraction)
 * Edit HERE only; the portal copy is generated. Feature CSS moves in later U6 chunks
 * together with its code (owner ruling D1 = A, 2026-09-23), not into this sheet.
 *
 * Cascade notes carried from the block: the rules keep their relative order, and the
 * recon's hazard analysis found no page rule of equal specificity that this move reorders
 * against (docs u6-recon-base-css.md §3, core scope). A later edit that makes a page
 * rule and a rule here tie on specificity must win in the page sheet, not here.
 */

/* --- THEME VARIABLES --- */
:root {
  /* Font Family Variables - Easy to switch for comparison */
  --font-primary: sans-serif; /* Current system font (default) */
  --font-inter: 'Inter', sans-serif; /* Inter variable font */
  --font-custom-2: 'Merriweather Sans', sans-serif; /* Custom font option 2 */
  
  /* Active font - change this to compare fonts:
   *   var(--font-primary)   = sans-serif (default)
   *   var(--font-inter)     = Inter
   *   var(--font-custom-2)  = Merriweather Sans
   */

  --font-family: var(--font-inter);
  --header-font: var(--font-inter);
  
  --font-main: 13px;
  --font-small: 12px;
  --icon-size: 16px;
  --library-header-height: 44px;
  
  /* FIX: Enforce minimum height to prevent overlapping rows */
  --row-min-height: 24px; 
  
  /* Tree Alignment Vars */
  --indent: 20px; 
  --expander-width: 12px; /* Smaller circle (Tight fit) */
  
  /* Line Geometry */
  /* Center of Expander = 12px / 2 = 6px */
  --line-left: 6px; 
  --line-width: 1px;
  --line-color: #747690;
  --line-curve-radius: 6px;
  
  /* Colors */
  --bg-color: #1c1c1c;
  --text-color: #d1cfcf;
  --item-bg: #333333;
  --item-border2: #5c5c5c;
  --accent-color: #00ffee;

  /* ── CARD SURFACE (app-wide bevel + inset treatment) ──────────────
     The house look every framed surface wears: .library-card,
     .device-card, .library-group-card, .pinako-ai-card,
     .three-panel-chooser-btn, .pinako-modal and — since 2026-08-29 —
     every menu, popup, palette, panel box and toast.

     Three tokens instead of twenty duplicated shadow stacks, because
     the stack is IDENTICAL everywhere and only the surface's own
     background token changes. That also makes the light-mode variant a
     token override rather than a second rule per target: ~21 rules, not
     ~42, and the taste values live in ONE place.

     How to wear it (copy exactly — do NOT re-derive):
       border-top: none;              ← CRITICAL, see below
       border-left: none;
       border-right:  1px solid color-mix(in srgb, <own bg> var(--card-bevel-r), black);
       border-bottom: 1px solid color-mix(in srgb, <own bg> var(--card-bevel-b), black);
       box-shadow: var(--float-ring), <own drop shadow>, var(--card-inset);

     NO TOP/LEFT BORDER. Every card in the app draws only right+bottom
     and leaves top/left bare, so the dark bevel runs out into the inset
     highlight with nothing to collide with. Keep a full
     `border: 1px solid var(--item-border)` underneath and a light
     hairline meets a near-black one at each corner — the hard join the
     owner reported on 2026-08-29.

     Mix against the surface's OWN background token. Cards sit on
     --item-bg, menus and modals on --panel-bg. Using the other one
     draws a bevel that does not belong to the surface.

     box-shadow order is outer-first, insets last. --float-ring is the
     tight dark ring that hugs the edge for extra contrast (owner,
     2026-08-29); it layers OVER the existing soft drop shadow.

     IT IS TOP + LEFT ONLY, and that is deliberate (owner, 2026-08-29).
     The first version was a uniform `0 0 0 1px` spread, which reads
     THICKER on the right and bottom — those two sides already carry the
     1px bevel BORDER, so border + ring stacked to two dark pixels while
     top and left had one. Two offset shadows put the ring exactly where
     there is no border, so every side is 1px. Do not go back to a
     spread ring without also removing the bevel border.

     Nudge these values to retune every card surface at once. */
  --card-bevel-r: 30%;
  --card-bevel-b: 30%;
  --card-inset: inset -2px -2px 7px rgba(0, 0, 0, 0.35),
                inset 2px 2px 4px rgba(255, 255, 255, 0.15),
                inset -1px -1px 5px rgba(0, 0, 0, 0.2),
                inset 1px 1px 1px rgba(255, 255, 255, 0.15),
                inset -1px -1px 3px rgba(0, 0, 0, 0.3);
  /* A frozen copy of --card-inset for the overlay (see the ::after block
     near the bottom of this sheet). Because a custom property is
     substituted on the element that DECLARES it, this holds the literal
     stack from here on and a descendant that overrides --card-inset
     cannot reach it. That is the whole point: a surface with an overlay
     sets its own --card-inset to a no-op so it stops double-drawing the
     frame, while the overlay keeps painting the real one. */
  --card-frame: var(--card-inset);
  /* The CARD stack: what .library-card, .library-group-card and
     .panel-menubox wear. Dark mode: the same stack as --card-inset.
     Light mode adds a 0.8px hairline (owner 2026-09-17), which the
     floating surfaces do not carry — hence a token of its own. */
  --lib-card-inset: var(--card-inset);
  --float-ring: -1px 0 0 0 rgba(0, 0, 0, 0.5),
                0 -1px 0 0 rgba(0, 0, 0, 0.5);

  /* Menu & UI Colors */
  --menu-shadow: rgba(0,0,0,0.5);
  --row-active-bg: #341679;
  --row-active-text: #fff;
  --icon-color: #aaa;
  --tree-icon-color: #aaa;
  --icon-hover-bg: rgba(255, 255, 255, 0.1);
  --icon-hover-color: #fff;
  --search-match-bg: #635d0e;
  --search-active-bg: #9e6300;
  --search-clear-color: #ff5252;

  /* Derived variables - these use color-mix() and require JS recalculation
     when customizer changes --bg-color or --item-bg. See recalculateDerivedColors() in pinako.js */
  --toolbar-bg: color-mix(in srgb, var(--bg-color), white 2%);
  --item-hover: color-mix(in srgb, var(--item-bg), white 10%);
  --item-border: color-mix(in srgb, var(--item-bg) 84%, white);
  --panel-bg: color-mix(in srgb, var(--item-bg), black 10%);
  --toolbar-border: #444;
  --split-border: #444;
  --accent2-color: #a52cdd;
  --accent2-row-bg: color-mix(in srgb, var(--accent2-color) 70%, black 30%);
  --text-secondary: color-mix(in srgb, var(--text-color) 75%, transparent);
  --text-muted: color-mix(in srgb, var(--text-color) 55%, transparent);
  --bg-secondary: #1e1e1e;
  --scrollbar-width: 13px;
  --motion-fast: 120ms;
  --motion-normal: 160ms;
  --motion-ease-out: cubic-bezier(0.22, 1, 0.36, 1);

  /* Enable transitions to/from sizing keywords (height: auto, min-content,
     etc.), Chrome 129+. Inherited app-wide. Audited safe: the only existing
     transitions on size properties are length-to-length (max-height ~2020,
     min-height ~4471, width ~5062) and are unaffected by this; it only
     powers the height:auto accordion transition on .user-guide-toc-children
     (and any future accordion). Browsers without support ignore it and keep
     the prior snap-to-size behavior. */
  interpolate-size: allow-keywords;

  --fx-row-depth: 1;
  --fx-search-focus: 1;
  /* Panel slide animation timing (editable in DevTools).
     Slide-IN uses a GENTLE under-damped spring (--spring-soft): the panel
     travels most of the way with an ease-out feel and settles with only a
     ~1.4% overshoot (~6px on a wide panel) -- a whisper of bounce, not a
     lurch. (An earlier, stiffer spring front-loaded ~88% of the travel into
     the first fifth of the time and overshot ~9%, which read as "teleport
     then bounce"; this curve spreads the motion out and tones the settle
     right down.) Slide-OUT stays a crisp accelerating curve: things leaving
     should exit, not settle. */
  --spring-soft: linear(
    0, 0.09 6%, 0.22 12%, 0.42 20%, 0.60 28%, 0.74 36%,
    0.85 44%, 0.93 52%, 0.98 60%, 1.008 68%, 1.014 75%,
    1.011 83%, 1.005 91%, 1
  );
  --slide-in-duration: 470ms;
  --slide-in-easing: var(--spring-soft);
  --slide-out-duration: 250ms;
  /* Close-both cascade (full close from 3-panel / expanded library): each
     panel exits at this longer duration, and the inner panel starts
     PANEL_CASCADE_STAGGER_MS (pinako.js) into the outer's exit -- ~65% of
     the way through. On the accelerating exit curve the outer panel is
     ~half traveled and at high velocity at that moment, so its fast finish
     overlaps the inner's slow start: one chained outer-to-inner collapse
     instead of two blinks with a dead beat between them. */
  --slide-out-duration-cascade: 340ms;
  --slide-out-easing: cubic-bezier(0.4, 0, 1, 1);
}

body.light-mode {
  --bg-color: #d6cdba;
  --text-color: #333333;
  --item-bg: #c9b999;
  --line-color: #9c716a;
  --accent-color: #ed6f26;
  --menu-shadow: rgba(0,0,0,0.1);
  --row-active-bg: #f7aa52;
  --row-active-text: #333;
  --icon-color: #363636;
  --tree-icon-color: #888;
  --icon-hover-bg: rgba(0, 0, 0, 0.1);
  --icon-hover-color: #333;
  --search-match-bg: #fff59d;
  --search-active-bg: #ffcc80;
  --search-clear-color: #d32f2f;
  --toolbar-border: #ccc;
  --split-border: #ccc;
  --accent2-color: #706712;
  --accent2-row-bg: color-mix(in srgb, var(--accent2-color) 70%, white 30%);
  --text-secondary: color-mix(in srgb, var(--text-color) 75%, transparent);
  --text-muted: color-mix(in srgb, var(--text-color) 55%, transparent);
  --bg-secondary: #c4b89e;
  /* Derived variables - see comment in dark mode */
  --toolbar-bg: color-mix(in srgb, var(--bg-color), white 2%);
  --item-hover: color-mix(in srgb, var(--item-bg), black 5%);
  --item-border: color-mix(in srgb, var(--item-bg) 84%, white);
  --panel-bg: color-mix(in srgb, var(--item-bg), black 10%);
  /* Card surface — light mode is a DIFFERENT stack, not the dark one
     re-tinted: the dark-mode highlights read as grime on a light ground,
     so the light/dark weights are swapped. Copied from
     `body.light-mode .library-card`. The ring softens too — a 0.5 ring
     that reads as definition on a dark ground reads as a hard outline
     on a light one. */
  --card-bevel-r: 60%;
  --card-bevel-b: 65%;
  --card-inset: inset 2px 2px 6px rgba(255, 255, 255, 0.25),
                inset -2px -2px 7px rgba(0, 0, 0, 0.25),
                inset 1px 1px 4px rgba(255, 255, 255, 0.45),
                inset -1px -1px 2px rgba(0, 0, 0, 0.2),
                inset 1px 1px 1px rgba(255, 255, 255, 0.35),
                inset -1px -1px 1px rgba(0, 0, 0, 0.15);
  /* Re-frozen against the light stack — see the dark-mode note. */
  --card-frame: var(--card-inset);
  --lib-card-inset: inset 2px 2px 6px rgba(255, 255, 255, 0.25), inset -2px -2px 7px rgba(0, 0, 0, 0.25), inset 1px 1px 4px rgba(255, 255, 255, 0.45), inset -1px -1px 2px rgba(0, 0, 0, 0.2), inset 1px 1px 1px rgba(255, 255, 255, 0.35), inset -1px -1px 1px rgba(0, 0, 0, 0.15), inset 0.8px 0.8px 0.8px rgba(0, 0, 0, 0.25);
  --float-ring: -1px 0 0 0 rgba(0, 0, 0, 0.22),
                0 -1px 0 0 rgba(0, 0, 0, 0.22);
}

* { box-sizing: border-box; }

/* Keyboard focus visibility. The color is mixed HERE, not read from a
   :root custom property: the theme customizer writes --accent-color
   inline on <body>, so a :root-declared ring froze at the stylesheet's
   default accent and ignored the user's theme. */
:where(
  button,
  [role="button"],
  a[href],
  input:is([type=checkbox], [type=radio], [type=range], [type=file], [type=button], [type=submit], [type=reset]),
  summary,
  .menu-item,
  .library-tab,
  .icon-btn
):focus-visible {
  outline: 2px solid color-mix(in srgb, var(--accent-color) 65%, transparent);
  outline-offset: 2px;
  border-radius: 6px;
}

.custom-tooltip {
  /* Base state: Hidden and slightly offset */
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.custom-tooltip.visible {
  /* Active state: Visible and in original position */
  opacity: 1;
  transform: translateY(0);
}

/* Scrollbars: match theme */
/* WebKit */
	  /* 1. The Scrollbar Container */
	::-webkit-scrollbar {
		width: var(--scrollbar-width, 13px);
		height: var(--scrollbar-width, 13px);
	}

	/* 2. The Background (Track) */
	::-webkit-scrollbar-track {
		background: transparent; 

	}

	/* 3. The Draggable Handle (Thumb) */
	::-webkit-scrollbar-thumb {
		background: color-mix(in srgb, var(--accent-color) 55%, black);
		border-radius: 0 8px;
		border: 3px solid transparent;
		background-clip: padding-box;
		box-shadow:
			inset 1px 1px 0 0 rgba(0, 0, 0, 0.3),
			inset 2px 2px 0 0 rgba(0, 0, 0, 0.15),
			inset -1px -1px 0 0 rgba(0, 0, 0, 0.3),
			inset -2px -2px 0 0 rgba(0, 0, 0, 0.15);
}
::-webkit-scrollbar-thumb:hover {
  /* Dark mode (default): lighten on hover */
		border: 3px solid transparent;
  background: var(--accent-color);
		background-clip: padding-box;
		box-shadow:
			inset 1px 1px 0 0 rgba(0, 0, 0, 0.3), 
			inset 2px 2px 0 0 rgba(0, 0, 0, 0.22),
			inset 3px 3px 0 0 rgba(0, 0, 0, 0.14),  
			inset -1px -1px 0 0 rgba(0, 0, 0, 0.3), 
			inset -2px -2px 0 0 rgba(0, 0, 0, 0.22),
			inset -3px -3px 0 0 rgba(0, 0, 0, 0.14)
}

	  body.light-mode ::-webkit-scrollbar-thumb {
		border: 3px solid transparent;
		background: var(--accent-color);
		background-clip: padding-box;
		box-shadow:
			inset 1px 1px 0 0 rgba(0, 0, 0, 0.3),
			inset 2px 2px 0 0 rgba(0, 0, 0, 0.22),
			inset 3px 3px 0 0 rgba(0, 0, 0, 0.14),
			inset -1px -1px 0 0 rgba(0, 0, 0, 0.3),
			inset -2px -2px 0 0 rgba(0, 0, 0, 0.22),
			inset -3px -3px 0 0 rgba(0, 0, 0, 0.14);
}

/* Light mode: lighten on hover */
body.light-mode ::-webkit-scrollbar-thumb:hover {
		background: var(--accent-color);
		border-radius: 0 8px;
		border: 3px solid transparent;
		background-clip: padding-box;
		box-shadow:
			inset 0 0 0 1px rgba(0, 0, 0, 0.25),
			inset 1px 1px 0 0 rgba(0, 0, 0, 0.15),
			inset 2px 2px 0 0 rgba(0, 0, 0, 0.10),
			inset 3px 3px 0 0 rgba(0, 0, 0, 0.05),
			inset -1px -1px 0 0 rgba(0, 0, 0, 0.15),
			inset -2px -2px 0 0 rgba(0, 0, 0, 0.10),
			inset -3px -3px 0 0 rgba(0, 0, 0, 0.05);
}


    /* Invisible button for 'margin' at the top */
		::-webkit-scrollbar-button:vertical:start:decrement {
		display: block;
		height: 1px; 
		background-color: transparent;
}

.library-title-actions .toolbar-btn {
  width: 23px;
  height: 23px;
}

.menu-item { padding: 4.4px 12px; cursor: default; display: flex; align-items: center; font-size: var(--font-main); color: var(--text-color); }
.menu-item:hover { background: var(--item-hover); }
.menu-item.menu-focused { background: var(--item-hover); outline: none; }

.menu-item svg { margin-right: 8px; width: 16px; height: 16px; color: var(--icon-color); }
/* Context-menu fly-out panels (_buildContextMenuFlyoutRow). place() keeps
   a panel inside the gutter beside its owning menu rather than let it
   drift back over the menu and hide the rows below the hovered one, and
   narrows the panel with an inline max-width when the gutter is tighter
   than the natural width. Rows have to ellipsize inside that cap instead
   of pushing the box wide again — Copy to Library is sized by
   user-authored Library titles, so its natural width is unbounded. */
.menu-flyout-panel .menu-item { min-width: 0; }
.menu-flyout-panel .menu-item svg { flex-shrink: 0; }

.menu-compact .menu-item { padding: 2px 12px; }

/* ── Universal popup fit (owner rule 2026-08-21) ─────────────────────
   No popup may run off the bottom of the window. fitPopoverToViewport()
   measures a popover once it is built and, when it is taller than the
   room the window has left, writes a measured max-height inline and
   hangs this class on it — so the overflow scrolls INSIDE the popup
   instead of spilling past the edge. Only the pixel cap is inline (it is
   a measurement); everything static about the scrolling state lives
   here. overscroll-behavior stops the scroll chaining into the tree
   behind once the popup hits its end.
   padding-top:0 for the same reason .menu-compact carries it — the base
   6px would let rows scroll into the gap ABOVE the close-X.

   WHERE THE SCROLLING LIVES (owner 2026-08-30). It used to be on the
   popup itself, which cost two things: the close-X had to be
   position:sticky to stay reachable, and its opaque background then cut
   the card frame off at the top — while the ::after frame overlay could
   not be used at all, because an inset:0 overlay inside a scroller
   tracks scrollTop and slides away.

   The Connected Sources modal already had the answer. .pinako-modal is a
   frame that does NOT scroll, with a .pinako-modal-body that does inside
   it and the close X floated outside that body. Menus now use the same
   shape: rows go in a .menu-scroll child, the header sits outside it, and
   the menu is a flex column that clips. The header is pinned because it
   is not in the scrolled content, not because it is sticky; and the menu
   is no longer a scroll container, so the frame overlay works.

   The legacy path is kept for popups that have no .menu-scroll — the
   memo/tags/link popups reach fitPopoverToViewport too, and they have no
   header to pin, so scrolling the popup itself is still right for them. */
.popover-scrolls:not(:has(> .menu-scroll)) { overflow-y: auto; overscroll-behavior: contain; }

.popover-scrolls:has(> .menu-scroll),
.menu-compact:has(> .menu-scroll) {
  display: flex;
  flex-direction: column;
  /* clip, not hidden: the menu keeps its frame overlay, whose 1px overhang
     would give a hidden (scroll) box 1px of scroll; the .menu-scroll box
     inside is the one that scrolls. */
  overflow: clip;
}
/* A plain block in every menu — NOT display:contents any more. The
   floated close X needs something to reserve room for it, and padding on
   a display:contents box does nothing, so a short menu's first row ran
   under the X. Layout-neutral otherwise: nothing in this sheet or in the
   JS selects menu rows as DIRECT children of the menu (checked). */
.menu-scroll { display: block; }
/* Clearance for the floated X. On the menu it would push the scroll box
   (and its scrollbar) down again — this is the modal's `padding-top` on
   .pinako-modal-body, for the same reason. */
/* Tracks the button: 20px tall at top:4px ends at 24px, so 26px keeps
   the same 2px breathing space under it. Drop this below 24px and the
   first row slides under the X. */
.menu-dropdown:has(> .menu-context-header) > .menu-scroll { padding-top: 26px; }
.popover-scrolls > .menu-scroll,
.menu-compact > .menu-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.toolbar-btn, .nav-btn { background: transparent; border: none; cursor: default; color: var(--icon-color); display: flex; align-items: center; justify-content: center; border-radius: 4px; }
.toolbar-btn, .nav-btn, .menu-item, .library-tab {
  /* Micro-transitions (transform added for §4.3 press feedback) */
  transition: box-shadow 0.15s ease, color 0.15s ease, opacity 0.15s ease, transform 80ms var(--motion-ease-out);
}
.toolbar-btn {
		width: 24px;
		height: 24px;
		padding: 0;
		flex: 0 1 24px;
		max-width: 24px;
		min-width: 12px;
		}

#btn-collapse-all, #btn-expand-all,
#secondary-search-container > .toolbar-btn,
.collapse-flyout > .toolbar-btn { width: 24px; height: 24px; flex: 0 1 24px; max-width: 24px; }

/* Icon size is driven by JS via --toolbar-icon; stays 16px until button is less than 16px. */
.toolbar-btn svg { width: var(--toolbar-icon, 16px) !important; height: var(--toolbar-icon, 16px) !important; max-width: 100%; max-height: 100%; }

.toolbar-btn:hover, .nav-btn:hover { box-shadow: 0 0 6px color-mix(in srgb, var(--accent2-color) 60%, transparent), inset 0 0 5px color-mix(in srgb, var(--accent-color) 30%, transparent); }
#toolbar-inner > .toolbar-btn { transition: box-shadow 0.15s ease, transform 0.13s cubic-bezier(0.22, 1, 0.36, 1); }
#toolbar-inner > .toolbar-btn:hover { transform: translateY(-1px) scale(1.03); }
#toolbar-inner > .toolbar-btn:active { transform: translateY(0) scale(0.98); }

#global-notes-wrapper > .library-tabs-wrapper {
  position: static;
  z-index: auto;
  flex-shrink: 0;
}

/* The Home Tab Sets file-tabs bar reuses .library-tabs-wrapper, which is
   sticky so it can pin under a library header. This panel has no such
   header inside its scroll area, so sticky just made the bar detach and
   float 44px down whenever a long list scrolled. Keep it in normal flow. */
#panel-secondary .panel-scroll.panel-scroll-hometabs .library-tabs-wrapper {
  position: static;
  z-index: auto;
  flex-shrink: 0;
}

.flat-row-container {
  display: block;
  width: 100%;
  position: relative;
}

/* Flat rows base styling */
.flat-row {
  /* padding-left is set inline based on depth */
  box-sizing: border-box;
  user-select: none;
}

/* Depth-based visual styling for flat rows */
.flat-row-container.depth-0 > .flat-row > .row-content > .row-title {
  font-weight: bold;
  font-size: 14px;
}

/* Collapsed indicator for flat rows */
.flat-row-container.collapsed > .flat-row > .row-expander {
  opacity: 0.6;
}

/* Leaf node styling (no opacity reduction) */
.flat-row-container.leaf > .flat-row > .row-expander {
  pointer-events: none;
  background-color: transparent;
}

/* Hover state for flat rows - use --row-current-bg for consistency with btn-group */
.flat-row-container:hover > .flat-row > .row-content {
  --row-current-bg: var(--item-hover);
}
.flat-row-container:hover > .flat-row.window > .row-content,
.flat-row-container:hover > .flat-row.folder > .row-content {
  --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-hover) 85%);
}
/* Group rows with row color - apply 10% white overlay to group color instead of default hover */
.flat-row-container:hover > .flat-row > .row-content.has-row-color {
  --row-current-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 14%, var(--item-bg)), white 10%);
  --row-accent-edge-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 50%, var(--item-bg)), white 10%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
.flat-row-container:hover > .flat-row > .row-content.has-row-color.row-color-custom {
  --row-current-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 28%, var(--item-bg)), white 10%);
  --row-accent-edge-bg: color-mix(in srgb, var(--group-row-bg), white 10%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}

/* Selection state (keyboard navigation / single-click).
   --row-accent-edge-bg holds the gradient's left-edge color so the
   absolutely-positioned indent-outdent-group can match it instead of
   showing a solid block that cuts the gradient off. */
.flat-row-container.node-selected > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 7%, var(--item-bg) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent-color) 25%, var(--item-bg) 75%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
.flat-row-container.node-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 7%, var(--item-hover) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent-color) 25%, var(--item-hover) 75%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}

/* Light mode: stronger accent visibility for selection */
body.light-mode .flat-row-container.node-selected > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 7%, var(--item-bg) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent-color) 55%, var(--item-bg) 45%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
body.light-mode .flat-row-container.node-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 7%, var(--item-hover) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent-color) 55%, var(--item-hover) 45%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}

/* Home tabs selection mode: Tab row hover effect */
body.home-tabs-selection-mode .flat-row-container:hover > .flat-row.tab > .row-content {
  box-shadow: 0 0 5px color-mix(in srgb, var(--accent-color) 65%, transparent);
}

/* Home tabs selection mode: Disable hover effect on window/group nodes */
body.home-tabs-selection-mode .flat-row-container:hover > .flat-row.window > .row-content,
body.home-tabs-selection-mode .flat-row-container:hover > .flat-row.group > .row-content {
  cursor: default;
}

/* Home tabs selection mode: Change node-selected from accent-color to accent2-color */
body.home-tabs-selection-mode .flat-row-container.node-selected > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent2-color) 7%, var(--item-bg) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent2-color) 25%, var(--item-bg) 75%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
body.home-tabs-selection-mode .flat-row-container.node-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent2-color) 7%, var(--item-hover) 93%);
  --row-accent-edge-bg: color-mix(in srgb, var(--accent2-color) 25%, var(--item-hover) 65%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}

/* Home tab selected state - Dark mode */
.flat-row-container.home-tab-selected > .flat-row > .row-content {
  --row-current-bg: #0b5a23;
}
.flat-row-container.home-tab-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, #0b5a23 85%, white 15%);
}
/* Home tab selected state - Light mode */
body.light-mode .flat-row-container.home-tab-selected > .flat-row > .row-content {
  --row-current-bg: #08782a;
}
body.light-mode .flat-row-container.home-tab-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, #08782a 85%, black 15%);
}

/* Dragging states for flat rows */
body.drag-active .flat-row-container {
  pointer-events: auto;
}

.flat-row-container.pointer-drag-source > .flat-row > .row-content {
  opacity: 0.4;
}

/* --- ROW LAYOUT --- */
.tree-row {
  display: flex; align-items: center;
  /* Fix: Use Min-Height variable to prevent crush */
  min-height: var(--row-min-height);
  position: relative; width: 100%; padding: 0;
  user-select: none;

  /* CSS Containment: Isolate each row's layout calculations */
  contain: layout style;
  transition: transform calc(130ms * var(--fx-row-depth, 1)) cubic-bezier(0.22, 1, 0.36, 1);
}
.tree-row:hover,
.flat-row:hover {
  transform: translateY(calc(-0.35px * var(--fx-row-depth, 1)));
}

/* Generic SVG style (remove fixed width/height so attributes or specific rules apply) */
	  /* Magenta hue for collapsed icons */
.collapsed > .tree-row > .row-expander {
    color: var(--accent-color);

}

/* Leaf nodes show circle border */
.leaf > .tree-row > .row-expander {
    border-color: var(--tree-icon-color, #aaa);
    pointer-events: none;
		  background-color: transparent;
}

/* Leaf nodes show the small dot SVG */
.leaf > .tree-row > .row-expander svg { 
    display: block; 
    width: 6px; 
    height: 6px; 
}

/* CONTENT BOX */
.row-content {
   flex-grow: 1; height: 20px; display: flex; align-items: center;
   /* Single source of truth for row background - all overlays inherit this */
   --row-current-bg: var(--item-bg);
   background-color: var(--row-current-bg);
   border: 1px solid color-mix(in srgb, var(--row-current-bg) 88%, white);
   border-radius: 3px;
		 padding: 0 3px 0 6px;
   color: var(--text-color);
   min-width: 0; cursor: default;
   transition: background-color 0.1s;
   position: relative; z-index: 5;
}
.row-content:hover { --row-current-bg: var(--item-hover); }
body.light-mode .row-content {
  border: 1px solid color-mix(in srgb, var(--row-current-bg) 88%, black);
}

.row-content.row-active { --row-current-bg: var(--row-active-bg) !important; color: var(--row-active-text); }
/* Ghost/closed nodes: darken by reducing opacity (original behavior) */
.row-content.row-ghost { opacity: 0.54; color: color-mix(in srgb, var(--text-color), white 30%); }
body.light-mode .row-content.row-ghost { color: color-mix(in srgb, var(--text-color), black 99%); }
/* row-ghost-panel no longer used — ghost dimming is now skipped entirely in non-live panels */
/* Window and folder nodes: subtle accent background */
.tree-row.window .row-content, .tree-row.folder .row-content { --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-bg) 85%); }
.tree-row.window .row-content:hover, .tree-row.folder .row-content:hover { --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-hover) 85%); }

body.show-indent-outdent .row-content:hover .indent-outdent-group {
  display: flex;
}
/* While the chevrons show over a row, hide what they overlap so they
   read as bare strokes, not stacked on top of a favicon / folder icon /
   collapsed count. visibility (not display) keeps the layout box, so
   nothing shifts. Which element that is depends on the row: a collapsed
   row leads with its (n) badge, so the badge hides and the favicon /
   folder icon stays visible just right of the chevrons; an expanded row
   leads with the icon, so the icon hides. Containers keep their badge
   visible via order:-1 below since their buttons are always shown. */
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.tab > .row-content:not(.has-collapsed-count):hover > .row-icon,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.folder > .row-content:not(.has-collapsed-count):hover > .folder-icon,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.tab > .row-content.has-collapsed-count:hover > .collapsed-count,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.folder > .row-content.has-collapsed-count:hover > .collapsed-count {
  visibility: hidden;
}
/* The badge occupies the slot the 26px button group lands on, so it has
   to be at least that wide (20px + its 6px margin); without this a short
   count like (3) leaves the favicon sitting under the right chevron.
   A folder with a badge then no longer needs the widened icon margin
   below — the badge already reserves the room. */
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.tab > .row-content.has-collapsed-count > .collapsed-count,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.folder > .row-content.has-collapsed-count > .collapsed-count {
  min-width: 20px;
}
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.folder > .row-content.has-collapsed-count > .folder-icon {
  margin-right: 4px;
}

/* Non-tab rows have no favicon for the button group to overlay. When
   indent/outdent overlay is enabled on a nested row, reserve favicon-
   width space at the left so the title isn't clipped by the absolute-
   positioned button group. Windows/groups use the hidden row-icon as
   the spacer; folders widen their folder-icon's right margin so the
   26px button group fits cleanly.
   order: -1 pulls that spacer ahead of the collapsed-count badge so the
   permanently-visible buttons below don't sit on top of the count. */
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.window > .row-content > .row-icon,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.group > .row-content > .row-icon,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.tabgroup > .row-content > .row-icon {
  display: inline-block !important;
  visibility: hidden;
  order: -1;
}
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.folder > .row-content > .folder-icon {
  margin-right: 12px;
}

/* Container rows (window / window-group / tab-group) have no favicon for
   the buttons to trade places with, so hover-reveal leaves the reserved
   slot reading as an empty gap. Keep their buttons visible at all times
   while the option is on. Tabs and folders still reveal on hover, where
   the chevrons appear over (and hide) their real icon. */
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.window > .row-content > .indent-outdent-group,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.group > .row-content > .indent-outdent-group,
body.show-indent-outdent .flat-row-container.has-indent-outdent .tree-row.tabgroup > .row-content > .indent-outdent-group {
  display: flex;
}

.row-title {
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
		flex-grow: 1;
		font-size: var(--font-main);
		font-variation-settings: 'opsz' 26;  /* for Inter font use only*/
		line-height: 20px;
		}

.row-title:has(.rename-input) {
  display: flex;
  justify-content: flex-start;
}

/* Bold text for top-level window nodes (depth 0) */

/* Row action buttons: full-height overlay (doesn't reserve layout width when hidden) */
.btn-group {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 1px;
  opacity: 1;
  pointer-events: auto;
  /* Background automatically matches row via inherited --row-current-bg */
  background: var(--row-current-bg);
  padding: 0 1px 0 5px; /* default: date hidden */
  border-radius: 0; /* no radius */
  /* No inner top/bottom lines (prevents 2px-thick border illusion vs the row border) */
  box-shadow: none;
}
/* Window, Group, Tab Group and Folder rows: nudge buttons left a few px to
   align with tab rows. Tab rows get the same 3px for free from the
   .row-date-actions wrapper they nest their .btn-group inside; container
   rows put it straight in .row-content, so they need it declared. Session
   world's project folders (.folder.session-row) run their own button inset
   (session-ui.css), so they are left out. */
.tree-row.window > .row-content > .btn-group,
.tree-row.group > .row-content > .btn-group,
.tree-row.tabgroup > .row-content > .btn-group,
.tree-row.folder:not(.session-row) > .row-content > .btn-group { right: 3px; }
/* Soft fade on the left edge so the overlay doesn't hard-cut the title text */
.btn-group::before {
  content: '';
  position: absolute;
  left: -12px;
  top: 0;
  bottom: 0;
  width: 14px;
  pointer-events: none;
  background: linear-gradient(to right, transparent, var(--row-current-bg));
}

/* --- Button visibility rules --- */
/* Default (Show Date OFF):
   Only the first two buttons (Edit Title, Copy to Library) appear on hover.
   Note, Star, Close, Delete are always visible. */
.btn-group .hover-only { display: none; }
.row-content:hover .btn-group .hover-only,
.tree-row:hover .btn-group .hover-only { display: flex; }

/* Copy/Move chooser open on a LIBRARY-tree row: the menu is appended to
   the body, so the moment the pointer lands on it the row stops being
   hovered and this .hover-only cluster would collapse — taking the
   menu's own anchor with it mid-choice. Hold the cluster until the menu
   closes. Tab-world twin of .session-row-container.session-menu-open. */
.tree-row.row-menu-open .btn-group .hover-only { display: flex; }

/* Show Date ON (tab rows): restore overlay behavior.
   Date sits above the right edge of the button row, covering Close/Delete.
   Only Note + Star are visible when not hovered; on hover, date fades out and all buttons fade in. */
/* Scoped to TAB rows only (.tree-row.tab) so the tab-world date overlay
   reserves the 7px that keeps the star clear of the date's left edge.
   Must NOT reach session rows (.session-row / .session-provider / etc.):
   they run their own always-on .session-date system and manage their own
   inset, so this rule bleeding onto them shifted their metadata. 7px is
   calibrated: less clips the star under the date (3px slid it ~4px under). */
body.show-opened-dates .tree-row.tab .btn-group {
  padding-right: 7px;
}
/* Container rows show no date, but with dates on their buttons still end on
   the tab rows' line (owner 2026-09-27: they sat 6px to the right of it). */
body.show-opened-dates .tree-row.window > .row-content > .btn-group,
body.show-opened-dates .tree-row.group > .row-content > .btn-group,
body.show-opened-dates .tree-row.tabgroup > .row-content > .btn-group,
body.show-opened-dates .tree-row.folder:not(.session-row) > .row-content > .btn-group {
  padding-right: 7px;
}
body.show-opened-dates .tree-row.tab .row-date-actions { position: relative; }
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group { z-index: 1; }
body.show-opened-dates .tree-row.tab .row-date-actions .row-date { z-index: 2; }

/* Fade behavior (cheap: opacity only) */
body.show-opened-dates .tree-row.tab .row-date-actions .row-date {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  padding: 0;
  margin-right: -2px;
  background: var(--row-current-bg);
  opacity: 1;
  transition: opacity 120ms ease;
}
body.show-opened-dates .tree-row.tab:hover .row-date-actions .row-date,
body.show-opened-dates .tree-row.tab .row-content:hover .row-date-actions .row-date {
  opacity: 0;
}

/* Button visibility: default only Memo+Star; hover shows all */
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group .icon-btn {
  opacity: 0;
  pointer-events: none;
  transition: opacity 120ms ease;
}
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group .btn-memo,
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group .btn-star,
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group .btn-tags {
  opacity: 1;
  pointer-events: auto;
}
body.show-opened-dates .tree-row.tab:hover .row-date-actions .btn-group .icon-btn,
body.show-opened-dates .tree-row.tab .row-content:hover .row-date-actions .btn-group .icon-btn {
  opacity: 1;
  pointer-events: auto;
}

/* Same hold under the Show Date overlay, where the cluster is
   opacity-driven rather than display-driven. */
body.show-opened-dates .tree-row.tab.row-menu-open .row-date-actions .btn-group .icon-btn {
  opacity: 1;
  pointer-events: auto;
}
body.show-opened-dates .tree-row.tab.row-menu-open .row-date-actions .row-date { opacity: 0; }

/* Avoid double-thick top/bottom outline when only Memo/Star are visible under the date overlay */
body.show-opened-dates .tree-row.tab .row-date-actions .btn-group {
  box-shadow: none;
}

/* Ungroup button (tab-group rows): its own rust tint, so the one verb
   with no other one-click route reads as distinct from the neutral row
   actions. Scoped to .btn-group = tree rows only; the library-card
   ungroup buttons share the class but live in .card-actions.
   Declared after .icon-btn:hover so the hover shift keeps the same hue
   instead of falling back to the neutral --icon-color mix. */
.btn-group .btn-ungroup { color: #984814; }
.btn-group .btn-ungroup:hover { color: color-mix(in srgb, #984814 60%, #fff); }
body.light-mode .btn-group .btn-ungroup { color: #c15008; }
body.light-mode .btn-group .btn-ungroup:hover { color: color-mix(in srgb, #c15008 70%, #000); }

.icon-btn:active, .nav-btn:active, .toolbar-btn:active {
  transform: scale(0.97);
  filter: brightness(0.92);
}
.menu-item.disabled { opacity: 0.6; cursor: default; }
.menu-item.disabled:hover { background: transparent; }

/* Metadata dots (calm-at-rest, consult 4.2): at rest a row shows only
   Close/Delete, plus the Star when it carries a color. Rows with a memo
   or tags render those buttons collapsed into small indicator dots
   (memo = yellow, tags = blue) just left of the star slot; the dots are
   non-interactive, so the hover-reveal can't cause a misclick. Hovering
   the row swaps dots for the full button cluster. Every reveal
   materializes to the LEFT of the pinned Close/Delete/colored-Star, so
   no resting click target ever shifts (suffix rule). The .btn-group
   background overlay + left fade auto-fit the visible content because
   all hiding is display-based (hidden buttons take no layout space).
   This replaces the removed Show Memo/Tags Button options and their
   pinned-order swap rules. */
.btn-group .btn-star:not(.has-star) { display: none; }
.btn-group .btn-memo:not(.has-memo) { display: none; }
/* .btn-tags is .hover-only (hidden at rest); tagged rows show its dot */
.btn-group .btn-tags.has-tags { display: flex; }

/* Dot rendering (rest): collapse the button box, hide the glyph, draw the dot */
.btn-group .btn-memo.has-memo,
.btn-group .btn-tags.has-tags {
  width: 8px;
  pointer-events: none;
}
.btn-group .btn-memo.has-memo svg,
.btn-group .btn-tags.has-tags svg { display: none; }
.btn-group .btn-memo.has-memo::before,
.btn-group .btn-tags.has-tags::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
}
.btn-group .btn-memo.has-memo::before { background: #e3b341; } /* yellow = memo */

.btn-group .btn-tags.has-tags::before { background: #1890ff; } /* blue = tags */

body.light-mode .btn-group .btn-memo.has-memo::before { background: #9a6700; }
body.light-mode .btn-group .btn-tags.has-tags::before { background: #0958a8; }

/* Hover: dots expand back into their real buttons; hidden buttons reveal */
.row-content:hover .btn-group .btn-star,
.tree-row:hover .btn-group .btn-star,
.row-content:hover .btn-group .btn-memo,
.tree-row:hover .btn-group .btn-memo { display: flex; }
.row-content:hover .btn-group .btn-memo.has-memo,
.tree-row:hover .btn-group .btn-memo.has-memo { width: 17px; pointer-events: auto; }
.row-content:hover .btn-group .btn-tags.has-tags,
.tree-row:hover .btn-group .btn-tags.has-tags { width: 18px; pointer-events: auto; }
.row-content:hover .btn-group .btn-memo.has-memo svg,
.tree-row:hover .btn-group .btn-memo.has-memo svg,
.row-content:hover .btn-group .btn-tags.has-tags svg,
.tree-row:hover .btn-group .btn-tags.has-tags svg { display: block; }
.row-content:hover .btn-group .btn-memo.has-memo::before,
.tree-row:hover .btn-group .btn-memo.has-memo::before,
.row-content:hover .btn-group .btn-tags.has-tags::before,
.tree-row:hover .btn-group .btn-tags.has-tags::before { content: none; }

/* Touch devices: no hover to reveal with -- keep real buttons, never dots */
@media (hover: none) {
  .btn-group .btn-star:not(.has-star),
  .btn-group .btn-memo:not(.has-memo) { display: flex; }
  .btn-group .btn-memo.has-memo { width: 17px; pointer-events: auto; }
  .btn-group .btn-tags.has-tags { width: 18px; pointer-events: auto; }
  .btn-group .btn-memo.has-memo svg,
  .btn-group .btn-tags.has-tags svg { display: block; }
  .btn-group .btn-memo.has-memo::before,
  .btn-group .btn-tags.has-tags::before { content: none; }
}

/* Pinako loader spinner — adapted from Pinako Pro portal.css for use during
   long-running in-extension operations (e.g. auto-organize sift). Theme-aware:
   the portal's hardcoded brand purple is driven from --accent-color via
   color-mix so the ring glows in whatever theme is active (white highlight
   kept). Single source — do not fork per surface. */
.loader-spinner {
  width: 56px;
  height: 56px;
  position: relative;
}
.loader-spinner::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent-color) 5%, transparent);
  box-shadow:
    0 0 6px 1px color-mix(in srgb, var(--accent-color) 20%, transparent),
    inset 0 0 6px 1px color-mix(in srgb, var(--accent-color) 20%, transparent);
}
.loader-spinner::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -3px;
  bottom: -3px;
  left: -3px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0%,
    transparent 60%,
    color-mix(in srgb, var(--accent-color) 0%, transparent) 70%,
    color-mix(in srgb, var(--accent-color) 70%, transparent) 86%,
    rgba(255, 255, 255, 0.92) 94%,
    color-mix(in srgb, var(--accent-color) 40%, transparent) 97.5%,
    color-mix(in srgb, var(--accent-color) 0%, transparent) 100%
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 3px), #000 calc(100% - 6px), transparent 100%);
  mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 3px), #000 calc(100% - 6px), transparent 100%);
  filter: blur(3px)
    drop-shadow(0 0 6px rgba(255, 255, 255, 0.5))
    drop-shadow(0 0 10px color-mix(in srgb, var(--accent-color) 65%, transparent));
  animation: loader-spin 0.8s linear infinite;
}
@keyframes loader-spin {
  to { transform: rotate(360deg); }
}

/* Group node row styling */
.tree-row.group > .row-content > .row-title {
  font-weight: bold;
  font-size: 14px;
}
/* Window node row styling - bold at any depth */
.tree-row.window > .row-content > .row-title {
  font-weight: bold;
  font-size: 14px;
}
/* Group rows don't show icons - same layout as window rows */
.tree-row.group .row-icon {
  display: none;
}

/* Tab Group node rows (containment model, N0; C7 rev. 2026-07-20):
   the title renders as a badge-pill in the group color - the node-scale
   version of the member badge and Chrome's own strip chip. JS stamps
   --tg-color/--tg-text (raw TAB_GROUP_COLORS pair); the row background
   stays the neutral container tint, same as window rows. */
.tree-row.tabgroup > .row-content > .row-title {
  background: var(--tg-color, var(--item-bg));
  color: var(--tg-text, inherit);
  font-weight: bold;
  font-size: 12px;
  line-height: 15px;
  padding: 0 6px;
  border: 1px solid transparent; /* reserved so the hover border doesn't shift layout */
  border-radius: 8px;
  flex-grow: 0;
  flex-shrink: 1;
  align-self: center;
  max-width: 70%;
  cursor: pointer;
}
/* The pill is a BUTTON (opens the Tab Group card): its own hover cue on
   top of the row hover — brightened group color + brighter border.
   Suppressed while a multi-select mode is active (row clicks toggle
   selection there; the pill click is disabled in JS too). */
body:not(.multi-select-mode) .tree-row.tabgroup > .row-content > .row-title:hover {
  background: color-mix(in srgb, var(--tg-color) 82%, white);
  border-color: color-mix(in srgb, var(--tg-color) 45%, white);
}
body.multi-select-mode .tree-row.tabgroup > .row-content > .row-title {
  cursor: inherit;
}
.tree-row.tabgroup .row-icon {
  display: none;
}
/* Untitled Chrome groups ('' title) get a muted placeholder label */
.tree-row.tabgroup > .row-content > .row-title.tabgroup-untitled {
  font-style: italic;
  opacity: 0.85;
}
/* Neutral container tint + hover, mirroring the window/folder rules */
.tree-row.tabgroup .row-content { --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-bg) 85%); }
.tree-row.tabgroup .row-content:hover { --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-hover) 85%); }
.flat-row-container:hover > .flat-row.tabgroup > .row-content {
  --row-current-bg: color-mix(in srgb, var(--row-active-bg) 15%, var(--item-hover) 85%);
}

/* Tab Group MEMBER rows: the expander/leaf circle fills with a
   theme-mixed group color (owner-tuned 2026-07-20: dark = 50% grey,
   light = 60% white); the outer ring border and the inner dot/delta
   SVG render above the fill. JS stamps the raw group color into
   --tg-color on the ROW. (The earlier row-bg tint was dropped - it
   mixed unreliably with existing row backgrounds.) Specificity: ties
   the .flat-row-container.leaf transparent-background rules at
   (0,4,0) and wins by source order. Remaining alternate to preview
   post-build: thin 1px color-mix (~25%) row border. */
.flat-row-container > .flat-row.tabgroup-member > .row-expander {
  background-color: color-mix(in srgb, var(--tg-color) 50%, grey);
}
body.light-mode .flat-row-container > .flat-row.tabgroup-member > .row-expander {
  background-color: color-mix(in srgb, var(--tg-color) 60%, white);
}

/* Row background color for Group nodes - default colors (50% blend with item-bg) */
/* Only set --row-current-bg; let base rule apply it via background-color: var(--row-current-bg) */
/* This ensures btn-group (which also uses --row-current-bg) always matches */
/* Hover applies same 10% white overlay as regular rows (matching --item-hover pattern) */
.row-content.has-row-color {
  --row-current-bg: color-mix(in srgb, var(--group-row-bg) 14%, var(--item-bg) 86%);
  --row-accent-edge-bg: color-mix(in srgb, var(--group-row-bg) 50%, var(--item-bg));
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
.row-content.has-row-color:hover {
  --row-current-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 14%, var(--item-bg)), white 10%);
  --row-accent-edge-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 50%, var(--item-bg)), white 10%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
/* Custom colors - full color, no blending */
.row-content.has-row-color.row-color-custom {
  --row-current-bg: color-mix(in srgb, var(--group-row-bg) 28%, var(--item-bg) 72%);
  --row-accent-edge-bg: var(--group-row-bg);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}
.row-content.has-row-color.row-color-custom:hover {
  --row-current-bg: color-mix(in srgb, color-mix(in srgb, var(--group-row-bg) 28%, var(--item-bg)), white 10%);
  --row-accent-edge-bg: color-mix(in srgb, var(--group-row-bg), white 10%);
  background: linear-gradient(to right,
    var(--row-accent-edge-bg) 10%,
    var(--row-current-bg) 60%
  );
}

/* .popup-btn retired 2026-08-30 — every one of its 52 call sites moved to
   .general-btn (the theme customizer's four) or .box-btn (all the rest).
   Only the save pulse survives, and it now rides the customizer's Save. */
.general-btn.save-success {
  animation: save-pulse 0.8s ease-out;
}
@keyframes save-pulse {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-color) 70%, transparent);
  }
  100% {
    box-shadow: 0 0 0 12px transparent;
  }
}

/* ── A ROW OF BUTTONS THAT GROW TOGETHER ─────────────────────────────
   The house rule for a row of sibling buttons in a narrow panel (owner
   2026-08-30). The theme customizer's Cancel / Reset / Save row already
   behaved this way and is the reference; this makes it a class rather
   than something each row re-derives.

   Three things make it work, and all three are needed:
   • flex:1 1 0 on the buttons — equal widths, so the row divides the
     space it has instead of overflowing it.
   • NO white-space:nowrap — that is what makes a long label wrap to a
     second line rather than spill past the button's border.
   • align-items:stretch (the flex default, restated so nobody "tidies"
     it away) — when one button takes two lines, ALL of them grow to
     match, so the row stays a rectangle.
   Vertical centring needs no rule: a <button> centres its own content,
   so the still-one-line buttons sit centred in the taller row. */
.btn-row-even {
  display: flex;
  align-items: stretch;
  gap: 6px;
}
.btn-row-even > .general-btn,
.btn-row-even > .box-btn,
.btn-row-even > button {
  flex: 1 1 0;
  min-width: 0;
  white-space: normal;
  text-align: center;
}

body.show-opened-dates .tree-row.tab .row-date-actions .row-date {
  display: flex; /* Shown when option active */
}

/* When date mode is on, give the date/pins strip the same top/bottom border line as the row */
/* Date-mode pinned/date strip: no extra border (title already ends before it). */

body.show-opened-dates .tree-row.tab:hover .row-date-actions .row-date {
  opacity: 0; /* Hide on hover (but keep width stable to avoid layout jump) */
}

/* Drop indicator is created dynamically in JS */

.dragging-source .row-content { opacity: 0.3; }

/* Source row during pointer drag */
.pointer-drag-source .row-content { opacity: 0.3; }

/* Armed long-press (rows, cards, cascades, note tabs): the element is
   "lifted" — moving starts the drag, lifting opens its context menu.
   Visual feedback matters because most touchscreen laptops have no
   vibration motor. */
.touch-drag-armed:not(.tree-row) {
    outline: 1px solid color-mix(in srgb, var(--accent-color), transparent 30%);
    outline-offset: -1px;
    border-radius: 4px;
    filter: brightness(1.12);
}
/* Tree rows: highlight only the row content, not the indent/tree-line band */
.tree-row.touch-drag-armed .row-content {
    outline: 1px solid color-mix(in srgb, var(--accent-color), transparent 30%);
    outline-offset: -1px;
    border-radius: 4px;
    filter: brightness(1.12);
}

/* Touch action for pointer events on tree rows.
   none: block all native browser gestures so programmatic scroll
   (in JS) handles 1-finger and 2-finger vertical panning, while
   long-press (400ms) reliably initiates drag without pointercancel. */
.tree-row {
    touch-action: none;
}

/* === DRAG PERFORMANCE OPTIMIZATIONS ===
   When body.drag-active, disable pointer-events on non-essential elements
   to prevent hover state recalculations during drag operations */

/* Disable hover effects on buttons/icons during drag - they're not clickable anyway */
body.drag-active .btn-group,
body.drag-active .row-expander,
body.drag-active .btn-close {
    pointer-events: none;
}

/* Keep flat-row-container and tree-row receiving pointer events for drop targeting */
body.drag-active .flat-row-container,
body.drag-active .tree-row {
    pointer-events: auto;
}

.panel-sync-tree .row-content { opacity: 1; }

/* Hover lifts the empty ring so an unpicked row still feels clickable. */
input[type=radio]:hover,
.sync-radio-option:hover .sync-radio-dot,
.port-mode-row:hover .port-mode-dot,
.send-to-menu .menu-item:hover .port-mode-dot {
  border-color: var(--icon-color);
}

/* Selected: ring takes the fill colour, dot springs out. */
input[type=radio]:checked,
.sync-radio-option.selected .sync-radio-dot,
.port-mode-row.selected .port-mode-dot,
.send-to-menu .menu-item.selected .port-mode-dot {
  border-color: var(--radio-fill, var(--accent-color));
}
input[type=radio]:checked::after,
.sync-radio-option.selected .sync-radio-dot::after,
.port-mode-row.selected .port-mode-dot::after,
.send-to-menu .menu-item.selected .port-mode-dot::after {
  transform: translate(-50%, -50%) scale(1);
  transition: transform 0.26s cubic-bezier(0.34, 1.45, 0.5, 1);
}

.library-tabs-wrapper {
  overflow: hidden; /* Prevent active-tab glow from spilling into content below */
  position: sticky; /* Sticky wrapper is more reliable than sticky inner bar */
  top: var(--library-header-height);
  z-index: 14;
  background: var(--toolbar-bg);
}

/* Fixed Link Tree tab */
.library-notes-toolbar > .library-tab.fixed-tab {
  flex-shrink: 0;
  margin-left: 0px;
}
/* Expand/Collapse library button — needs higher specificity than .fixed-tab above */
.library-notes-toolbar > .library-tab.fixed-tab.expand-library-btn {
  padding: 0;
  width: 24px;
  height: 24px;
  margin-left: 5px;
  margin-right: -1px;
  margin-bottom: 4px;
  border-radius: 9px;
  border: 1px solid var(--accent2-color);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Override library-tab gradient hover — use toolbar-btn glow instead */
.library-notes-toolbar > .library-tab.fixed-tab.expand-library-btn:hover {
  background: var(--item-bg);
  color: var(--icon-color);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent2-color) 60%, transparent), inset 0 0 5px color-mix(in srgb, var(--accent-color) 30%, transparent);
}

.toolbar-tabs-scroll::-webkit-scrollbar {
  display: none; /* Chrome/Safari/Opera */
}

.library-tab {
  position: relative;
  border: 1px solid color-mix(in srgb, var(--accent-color) 25%, transparent);
  border-bottom: none;
  background: var(--item-bg);
  color: var(--text-color);
  border-radius: 11px 11px 0 0;
  padding: 5px 12px;
  cursor: default;
  font-size: var(--font-small);
  /* No underline/shadow by default */
  box-shadow: none;
  flex-shrink: 0;
  align-self: flex-end;
  white-space: nowrap;
		margin-left: 5px;
}
.library-tab:hover {
  background: linear-gradient(to top, color-mix(in srgb, var(--accent-color) 25%, transparent) 0%, color-mix(in srgb, var(--accent-color) 14%, transparent) 25%, var(--item-bg) 100%);
  color: color-mix(in srgb, var(--accent-color) 10%, var(--text-color));
  z-index: 2;
}
.library-tab.draggable-note { cursor: move; }
.library-tab.draggable-note.dragging { opacity: 0.5; }
.library-tab.drag-over-left { box-shadow: -3px 0 0 0 var(--accent-color); }
.library-tab.drag-over-right { box-shadow: 3px 0 0 0 var(--accent-color); }
.library-tab.active {
  background: linear-gradient(to top, color-mix(in srgb, var(--accent-color) 17%, transparent) 0%, color-mix(in srgb, var(--accent-color) 14%, transparent) 12%, var(--item-bg) 100%);
  border-color: var(--toolbar-border);
  color: color-mix(in srgb, var(--accent-color) 10%, var(--text-color));
  z-index: 2;
}
/* Active blue outline and glow only on left/top/right */
.library-tab.active::before {
  content: '';
  position: absolute;
  left: -1px;
  right: -1px;
  top: -1px;
  bottom: -1px;
  border-radius: 11px 11px 0 0;
  pointer-events: none;
  border: 1px solid color-mix(in srgb, var(--accent-color) 70%, transparent);
  border-bottom: none;
  box-shadow: 0px 0px 5px var(--glow-rgba, rgba(60, 0, 224, 0.78));
  clip-path: inset(-5px -5px 0 -5px); /* clip bottom glow */
}

/* Selection mode: Tab row hover effect (only for tab nodes) */
body.home-tabs-selection-mode .tree-row.tab > .row-content:hover {
  box-shadow: 0 0 5px color-mix(in srgb, var(--accent-color) 65%, transparent);
}

/* Selection mode: Disable hover effect on window/group nodes */
body.home-tabs-selection-mode .tree-row.window > .row-content:hover,
body.home-tabs-selection-mode .tree-row.group > .row-content:hover {
  cursor: default;
}

/* Selected rows: accent tint on the row pill (survives hover) */
.flat-row-container.multi-selected > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 22%, var(--item-bg) 78%);
}
.flat-row-container.multi-selected:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 32%, var(--item-hover) 68%);
}

/* Hover cue ONLY on rows of the mode's locked type, inside the owning panel.
   Folders answer to BOTH modes (cascade toggles in tabs mode — owner
   spec 2026-08-12), so they carry the cue in each. */
body.multi-select-mode-tree .multi-select-owner .tree-row.tab > .row-content:hover,
body.multi-select-mode-tree .multi-select-owner .tree-row.tabgroup > .row-content:hover,
body.multi-select-mode-tree .multi-select-owner .tree-row.window > .row-content:hover,
body.multi-select-mode-tree .multi-select-owner .tree-row.group > .row-content:hover,
body.multi-select-mode-tree .multi-select-owner .tree-row.folder > .row-content:hover {
  box-shadow: 0 0 5px color-mix(in srgb, var(--accent-color) 65%, transparent);
}

/* ── Duplicate review ────────────────────────────────────────────────
   Every copy of a repeated link carries .dup-hit; the one the HUD arrows
   are parked on also carries .dup-cursor. The tint rides
   --row-current-bg like the multi-select one, so it survives hover and
   composes with the row's own colour; the cursor adds an inset ring
   rather than a heavier fill, which stays legible on top of a search
   match's yellow. */
.flat-row-container.dup-hit > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 18%, var(--item-bg) 82%);
}
.flat-row-container.dup-hit:hover > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 28%, var(--item-hover) 72%);
}
.flat-row-container.dup-cursor > .flat-row > .row-content {
  --row-current-bg: color-mix(in srgb, var(--accent-color) 34%, var(--item-bg) 66%);
  outline: 1px solid var(--accent-color);
  outline-offset: -1px;
}

/* ...except on a popup that scrolls ITSELF, where the overlay is switched
   off (see below) and the host is the only thing left to draw the frame.
   A menu with a .menu-scroll box does NOT qualify: the box scrolls, the
   menu does not, so the overlay still works there and the host must stay
   out of it. Listed after the block above so it wins on source order. */
.popover-scrolls:not(:has(> .menu-scroll)),
.menu-compact:not(:has(> .menu-scroll)) {
  --card-inset: var(--card-frame);
}
/* A popup that scrolls ITSELF cannot use the overlay. An inset:0 box is
   positioned against the scroller's PADDING BOX and then scrolls with
   the content — measured on a live popup, it tracks scrollTop 1:1 — so
   the frame would slide up out of the box on the first wheel tick. Those
   keep the host's own inset box-shadow, which is painted on the border
   box and does not scroll.
   This is now only the LEGACY path: the memo/tags/link popups, which
   reach fitPopoverToViewport but have no header to pin. Menus moved
   their rows into .menu-scroll (owner 2026-08-30), so the menu itself
   stopped scrolling and keeps the overlay — which is the whole reason
   that restructuring was worth doing. */
.popover-scrolls:not(:has(> .menu-scroll))::after,
.menu-compact:not(:has(> .menu-scroll))::after {
  display: none;
}

/* Custom tooltips (replacement for native title tooltips) */
.custom-tooltip {
  position: fixed;
  z-index: 200000;
  padding: 2px 5px;
  font-size: 10.5px;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
  border-radius: 4px; 
  background: rgba(32, 32, 32, 0.96); /* dark mode */
  color: #c4c4c4;
  border: 1px solid rgba(0, 0, 0, 0.45);
  box-shadow: 0 4px 10px rgba(0,0,0,0.35); /* subtle */
}
body.light-mode .custom-tooltip {
  background: rgba(255, 255, 255, 0.98); /* light mode */
  color: #2c2c2c;
  border: 1px solid rgba(0, 0, 0, 0.18);
  box-shadow: 0 4px 10px rgba(0,0,0,0.18);
}
.custom-tooltip.custom-tooltip-secondary {
  /* same style; class exists to allow future overrides */
}
/* \v small-gap break (ensurePrimaryTooltipShown): the post-gap block
   gets ~60% of one line's height instead of a full blank line. */
.custom-tooltip .tt-tip-block { display: block; }
.custom-tooltip .tt-tip-gap { margin-top: 0.72em; }
/* Authored \n line breaks (data-tooltip-class="tt-multiline"). The base
   tooltip is nowrap, which collapses \n to a space; pre-line honors it.
   Only the FIRST \v break is free (ensurePrimaryTooltipShown splits on
   it), so any tooltip needing three or more lines needs this class.
   Lives HERE, not only in sessions.js's injected sheet, because that
   sheet arrives with the session ROW styles — and two tooltips that use
   this class sit outside the sessions workspace: the auto-organize
   trash button, and the Connected Sources card as mounted in the AI
   settings popup (pinako.js renderConnectedSourcesCard). sessions.js
   keeps an identical copy for its own sheet; same declaration, so
   whichever lands last is a no-op. */
.custom-tooltip.tt-multiline { white-space: pre-line; text-align: left; }
/* Top-layer + CSS anchor positioning (§3.9 Stage A). Progressive
   enhancement: when the browser supports anchor positioning (Chrome
   125+), the tooltip state machine renders tooltips in the top layer via
   popover="manual" and adds .anchored / .anchored-secondary so placement
   comes from anchor() instead of the JS positioning math. flip-block
   replaces the manual "flip above when no room below" logic; anchor-center
   replaces the centering math; position-visibility auto-hides the tooltip
   if its anchor scrolls out of view. Unsupported browsers skip this block
   and keep the JS fallback path. The entrance fade (opacity/transform via
   .visible) still applies -- it composes on top of the anchored position. */
@supports (anchor-name: --a) {
  .custom-tooltip.anchored {
    position: fixed;
    position-anchor: --tt-anchor;
    top: anchor(bottom);
    justify-self: anchor-center;
    margin-top: 8px;
    position-try-fallbacks: flip-block;
    position-visibility: anchors-visible;
  }
  .custom-tooltip.anchored-secondary {
    position: fixed;
    position-anchor: --tt-primary;
    top: anchor(bottom);
    justify-self: anchor-center;
    margin-top: 1px;
    position-try-fallbacks: flip-block;
    position-visibility: anchors-visible;
  }
  /* Corner placement variant (data-tooltip-class="tt-corner-br"):
     tooltip's top-left pinned near the target's bottom-RIGHT corner
     instead of centered below. Used by the tree-ops trigger, whose
     flyout menu opens directly below the button — a below-center
     tooltip would sit on top of the menu's first icon. margin-left
     clears the menu column (menu right edge ≈ trigger right + 8px). */
  .custom-tooltip.anchored.tt-corner-br {
    left: anchor(right);
    justify-self: auto;
    margin-left: 10px;
    margin-top: 4px;
  }
  /* Above placement variant (data-tooltip-class="tt-above"): used by the
     multi-select HUD, which floats ~10px off its panel's bottom edge —
     a below-center tooltip lands past the popup's bottom and gets
     clipped. Open upward instead. flip-block (inherited from .anchored)
     stays on as the safety net for the no-room-above case. */
  .custom-tooltip.anchored.tt-above {
    top: auto;
    bottom: anchor(top);
    margin-top: 0;
    margin-bottom: 8px;
  }
  /* Start-aligned variant (data-tooltip-class="tt-start"): the tooltip's
     LEFT edge lines up with its target instead of centering under it.
     For a WIDE tip on a target near the window's left edge, anchor-center
     would place it past x=0 and the clamp then parks it flush against the
     edge — technically visible, but sitting nowhere near the thing being
     hovered. span-right grows the tip rightward from the target's left
     edge, so it stays beside its item. flip-block (inherited) still
     handles the no-room-below case. */
  .custom-tooltip.anchored.tt-start {
    position-area: bottom span-right;
    justify-self: unset;
  }
}
/* Red error tooltip variant — used by sync error indicators.
   Shape copied from .drag-error-tooltip but kept smaller for toolbar use. */
.custom-tooltip.sync-error-tooltip {
  max-width: 320px;
  white-space: pre-wrap !important;
  word-wrap: break-word;
  padding: 6px 10px !important;
  font-size: 11px !important;
  line-height: 1.3 !important;
  background: #4a1212 !important;
  color: #fff !important;
  border: 1px solid #2d0a0a !important;
  border-radius: 6px !important;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4) !important;
}
body.light-mode .custom-tooltip.sync-error-tooltip {
  background: #5a1818 !important;
  color: #fff !important;
  border: 1px solid #3d0f0f !important;
}
/* Fixed-width, wrapping tooltip for the AI-search engine (i) explainers —
   the base .custom-tooltip is nowrap, which reads as one clipped line. */
.custom-tooltip.ai-mode-tip {
  max-width: 230px;
  white-space: normal !important;
  word-wrap: break-word;
  padding: 7px 10px !important;
  font-size: 11px !important;
  line-height: 1.4 !important;
}
/* The (i) icons sit at the right edge of the drawer rows, so the default
   anchor-center placement clamps flush to the window edge. Open the tooltip
   below-and-left instead, so it grows into the panel with a clean margin. */
@supports (anchor-name: --a) {
  .custom-tooltip.ai-mode-tip.anchored {
    position-area: bottom span-left;
    justify-self: unset;
    margin-right: 6px;
  }
}

.sync-divergence-buttons .general-btn {
  width: 100%;
  text-align: center;
  padding: 8px 16px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* A notes tab holding matches the user has not stepped to yet.
   ⚠ SESSION WORLD USES THE SAME TREATMENT, under its own class
   (.library-tab.sx-tab-has-match in Pinako/session-ui.css) — owner
   directive 2026-08-29: one look for both worlds, the dot is gone. The
   rule is spelled twice rather than shared because session-ui.css is
   quarantined out of dist while THIS rule has to ship in it. Keep the two
   gradients identical; change them together. */
.library-tab.note-has-search-match:not(.active) {
  background: linear-gradient(to top,
    color-mix(in srgb, var(--accent2-color) 100%, transparent) 0%,
    color-mix(in srgb, var(--accent2-color) 48%, transparent) 22%,
    color-mix(in srgb, var(--accent2-color) 42%, transparent) 35%,
    color-mix(in srgb, var(--accent-color) 30%, transparent) 100%);
}
