
/* ==== css/theme.css ==== */
/* Theme Variables - Simplified Color System */
/* Colors are loaded dynamically from /api/theme.css */

html {
    scrollbar-gutter: stable;
    --dashboard-bg-opacity: 1;
}

/* Background Patterns */
html[data-theme] body {
    background-color: var(--background-primary);
    color: var(--text-primary);
    isolation: isolate;
}

html[data-theme] body:not(.no-background-dots)::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: radial-gradient(var(--background-dots) 1px, transparent 1px);
    background-size: 15px 15px;
}

body.no-background-dots::before {
    content: none;
}

/* No Background Dots Option */
body.no-background-dots:not(.has-custom-background) {
    background-image: none !important;
}

/* Custom Background (auto / gradient / image) — ::after keeps opacity on the backdrop only */
body.has-custom-background::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-image: var(--custom-background-image);
    background-size: cover;
    opacity: var(--dashboard-bg-opacity, 1);
}

body.has-custom-background.bg-image::after {
    background-position: center center;
    background-repeat: no-repeat;
}

/* Preview icons in config */
.theme-icon-preview .preview-icon {
    width: 28px;
    height: 28px;
    display: inline-block;
    margin-right: 8px;
    border-radius: 6px;
    background: linear-gradient(135deg, rgba(255,255,255,0.06), rgba(0,0,0,0.06));
}

/* Themed icon wrappers and variants */
.icon-themed, .icon-themed img, .icon-themed .preview-icon {
    transition: filter .15s ease, opacity .15s ease, background-color .15s ease;
    border-radius: 6px;
}
.icon-themed--muted img, .icon-themed--muted .preview-icon {
    filter: grayscale(calc(var(--icon-theme-intensity, 0.6))); 
    opacity: calc(1 - (var(--icon-theme-intensity, 0.25) * 0.8));
}
.icon-themed--tinted img, .icon-themed--tinted .preview-icon {
    filter: saturate(calc(0.6 + var(--icon-theme-intensity, 0.4)));
    mix-blend-mode: multiply;
}
.icon-themed--tinted {
    background-color: color-mix(in srgb, var(--accent-primary) var(--icon-theme-intensity, 0.12), transparent);
}
/* A glyph is its own host — there is no <img> inside a category header's emoji
   — so the variants above, which reach for img/.preview-icon, would leave it at
   full colour beside harmonised favicons. Tinted deliberately skips the multiply
   blend the image rule uses: on text it eats the glyph rather than colouring it. */
.icon-themed--muted.icon-themed-glyph {
    filter: grayscale(calc(var(--icon-theme-intensity, 0.6)));
    opacity: calc(1 - (var(--icon-theme-intensity, 0.25) * 0.8));
}
.icon-themed--tinted.icon-themed-glyph {
    filter: saturate(calc(0.6 + var(--icon-theme-intensity, 0.4)));
}

.icon-themed--overlay {
    padding: 3px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-color: color-mix(in srgb, var(--accent-primary) var(--icon-theme-intensity, 0.12), transparent);
}


/* ── Focus styles (keyboard navigation) ── */

*:focus {
    outline: none;
}

input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 0;
}

button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.category-title:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-radius: 2px;
}

.search-command-group-header:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: -2px;
}

/* No Animations Option */
body.no-animations * {
    animation: none !important;
    transition: none !important;
    transform: none !important;
}

/* ==== css/layout-modern-tokens.css ==== */
/* Modern layout design tokens — the single definition of the modern visual
   language (radii, shadows, surfaces, motion).

   Every modern override file consumes these; none of them redefine a token.
   Load this BEFORE any stylesheet that reads a --layout-* value, so view CSS
   that ships modern rules of its own (health-view.css, config-view.css) can
   use the tokens without repeating them or guessing at fallbacks.

   Scoped to body[data-layout-version="modern"], so classic inherits nothing
   from this file and stays byte-for-byte the layout it always was. */

body[data-layout-version="modern"] {
    --layout-radius-sm: 8px;
    --layout-radius-md: 12px;
    --layout-radius-lg: 16px;
    --layout-radius-pill: 999px;
    --layout-shadow-sm: 0 1px 3px color-mix(in srgb, var(--text-primary) 8%, transparent);
    --layout-shadow-md: 0 4px 16px color-mix(in srgb, var(--text-primary) 12%, transparent);
    --layout-shadow-lg: 0 8px 28px color-mix(in srgb, var(--text-primary) 16%, transparent);
    --layout-gap-header: 1.25rem;
    --layout-transition: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    --layout-surface: color-mix(in srgb, var(--background-secondary) 78%, transparent);
    --layout-surface-border: color-mix(in srgb, var(--border-primary) 48%, transparent);
    --layout-focus-ring: 2px solid color-mix(in srgb, var(--accent-primary) 72%, transparent);
    --layout-overlay-bg: var(--background-modal, var(--background-secondary));
    --layout-modal-bg: var(--background-modal, var(--background-secondary));

    /* Accent wash used behind an active/hovered row. Kept as one gradient so a
       row reads as lit from the left edge rather than uniformly tinted. */
    --modern-bookmark-row-hover-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 58%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 32%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 10%, var(--background-primary)) 100%
    );
    --modern-bookmark-row-selected-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 68%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 38%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 16%, var(--background-primary)) 100%
    );
    --modern-bookmark-row-dimmed-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 7%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 3%, var(--background-primary)) 100%
    );
    --bookmark-row-hover-bg: var(--modern-bookmark-row-hover-bg);
    --bookmark-row-selected-bg: var(--modern-bookmark-row-selected-bg);
    --bookmark-row-dimmed-bg: var(--modern-bookmark-row-dimmed-bg);
}

/* ==== css/dashboard.css ==== */
/* Dashboard Styles */
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Remove tap highlight on mobile devices */
button,
a,
input,
select,
textarea,
[role="button"],
.clickable {
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
}

/*
 * Reserve the scrollbar's width whether or not the page scrolls. Without this,
 * a short section (Pages & tags, a filtered list) has no scrollbar and a tall
 * one does, so switching between them changed the usable width and every
 * centred layout — config's nav column most visibly — jumped sideways. Safari
 * and Firefox on macOS reserve real width for a scrollbar; browsers with
 * overlay scrollbars never showed the shift, which is why it reads as a
 * platform bug rather than a layout one.
 */
html {
    scrollbar-gutter: stable;
}

body {
    min-height: 100vh;
    transition: background-color 0.3s ease, color 0.3s ease;
    font-size: var(--font-size-text);
    /* clip, not hidden: `overflow-x: hidden` promotes the other axis from
       visible to auto, which made body its own scroll container (computed
       "hidden auto") instead of letting the viewport scroll the page. That is
       why an overlay's body-level scroll lock could strand the page and why the
       scrollbar visibly belonged to body. clip suppresses horizontal overflow
       without creating a scroll container. layout-modern.css already uses it. */
    overflow-x: clip;
    width: 100%;
}

/* Dashboard Sections */
.dashboard-section {
    padding: 0;
}

.dashboard-section.section-controls {
    padding-top: 2rem;
    padding-bottom: 0;
}

.dashboard-section.section-title {
    padding-top: 0;
    padding-bottom: 0;
}

.dashboard-section.section-content {
    padding-top: 0;
    padding-bottom: 8rem;
}

.container {
    /* Fixed clamp() side margin (not a percentage) so the whitespace shrinks
       toward the floor as the window narrows, giving the columns the reclaimed
       space before they have to get narrower. Roomy margins keep the columns
       closer together on wide screens.

       The clamp is the "balanced" value of the side-margin setting, so a
       dashboard that never touches the setting looks exactly as it always has;
       the fallback here repeats it for the case where no body attribute is set
       at all (a view rendered before setupDOM runs). */
    max-width: 1600px;
    width: 100%;
    margin: 0 auto;
    padding: 0 var(--dashboard-side-margin, clamp(2rem, 6vw, 8rem));
}

/* Left/right band beside the grid.
 *
 * Each keeps a clamp so the margin still collapses on a narrow window rather
 * than squeezing the columns — only the ceiling differs. "snug" hands roughly
 * 100px per side back to the grid on a wide screen; "airy" is for people who
 * want the columns pulled together. */
body[data-side-margin="snug"] {
    --dashboard-side-margin: clamp(1rem, 2.5vw, 3rem);
}
body[data-side-margin="balanced"] {
    --dashboard-side-margin: clamp(2rem, 6vw, 8rem);
}
body[data-side-margin="airy"] {
    --dashboard-side-margin: clamp(3rem, 9vw, 12rem);
}

/* Header Top - Contains date, tabs, and config button */
.header-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.date {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: calc(var(--font-size-controls) * 1.2);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.2;
    color: var(--text-secondary);
}

.date-badge-mobile {
    display: none;
}

.date-time-line,
.date-weather-line {
    font-weight: var(--font-weight-semibold);
}

.date-weather-line--error {
    color: var(--text-secondary);
    font-size: calc(var(--font-size-controls) * 0.95);
    font-weight: var(--font-weight-normal, 400);
    opacity: 0.85;
}

.date-time-line {
    font-size: calc(var(--font-size-controls) * 1.3); /* slightly smaller */
    color: var(--text-secondary);
    cursor: pointer;
    user-select: none;
    border-radius: var(--layout-radius-sm, 8px);
    transition: opacity 0.12s ease;
}
.date-time-line:hover {
    opacity: 0.75;
}

/* ─── Date popover ───────────────────────────────────────────── */
.date-popover {
    position: fixed;
    z-index: 9000;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 12px;
    padding: 0.85rem 1rem 0.7rem;
    min-width: 210px;
    color: var(--text-primary);
    font-family: var(--font-family-main);
    box-shadow: 0 4px 18px color-mix(in srgb, var(--text-primary) 14%, transparent);
    animation: datePopoverIn 0.15s ease forwards;
}

@keyframes datePopoverIn {
    from { opacity: 0; transform: translateY(-6px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0)   scale(1);    }
}

.date-popover-week-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
    margin-bottom: 0.55rem;
}

.date-popover-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    text-align: center;
}

.date-popover-col-label {
    font-size: 0.62rem;
    color: var(--text-tertiary, var(--text-secondary));
    padding-bottom: 0.25rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.date-popover-day {
    font-size: 0.78rem;
    font-weight: var(--font-weight-semibold, 600);
    padding: 0.3rem 0;
    border-radius: 6px;
    line-height: 1;
    color: var(--text-primary);
}

.date-popover-day.is-weekend {
    color: var(--text-tertiary, var(--text-secondary));
}

.date-popover-day.is-today {
    background: color-mix(in srgb, var(--accent-primary) 22%, transparent);
    color: var(--text-primary);
}

.date-popover-footer {
    margin-top: 0.7rem;
    padding-top: 0.55rem;
    border-top: 1px solid var(--border-primary);
    text-align: center;
}

.date-popover-cal-link {
    font-size: 0.68rem;
    color: var(--text-secondary);
    text-decoration: none;
    transition: color 0.1s ease;
}
.date-popover-cal-link:hover {
    color: var(--accent-primary);
    text-decoration: underline;
}

/* ─── Move popover ───────────────────────────────────────────── */
.move-popover {
    position: fixed;
    z-index: 9000;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.65rem;
    padding: 0.35rem 0 0.45rem;
    min-width: 12rem;
    max-width: min(16rem, calc(100vw - 1rem));
    max-height: min(70vh, 20rem);
    overflow-y: auto;
    color: var(--text-primary);
    font-family: var(--font-family-main);
    box-shadow: 0 4px 18px color-mix(in srgb, var(--text-primary) 14%, transparent);
    animation: datePopoverIn 0.13s ease forwards;
}

/* The category menu sizes to what it holds.
 *
 * .move-popover is capped at 16rem for the move, tag and delete pickers, which
 * list every category, page or tag you have and want to stay narrow. This menu
 * is four fixed rows, and each carries the key that does the same thing — at
 * the shared cap the widest row needed 274px and got 237, so the chip was
 * quietly cut off by the ellipsis. Longer translations make that worse: the
 * French label for spreading is half again as long as the English one. */
#category-context-menu {
    width: max-content;
    max-width: min(24rem, calc(100vw - 1rem));
}

/* The bookmark context menu is a fixed, short action list — unlike the move,
   tag and delete popovers, which share .move-popover and list every category,
   page or tag you have and genuinely need to scroll.
   The shared 20rem cap was already within one item of this menu's height, so
   adding the two multi-select entries pushed it over: the last entries fell
   below the fold and a scrollbar appeared on a menu that is meant to be read at
   a glance. It sizes to its content instead, and only falls back to scrolling
   when the viewport itself is too short to hold it. */
.bookmark-context-menu {
    max-height: none;
    overflow-y: visible;
}

@media (max-height: 34rem) {
    .bookmark-context-menu {
        max-height: calc(100vh - 2rem);
        overflow-y: auto;
    }
}

.move-popover-header {
    font-size: calc(var(--font-size-controls) * 0.72);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
    padding: 0.4rem 0.85rem 0.25rem;
}

.move-popover-current-hint {
    padding: 0 0.85rem 0.55rem;
    font-size: calc(var(--font-size-controls) * 0.88);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    line-height: 1.35;
}

.move-popover-section-label {
    font-size: calc(var(--font-size-controls) * 0.68);
    font-weight: var(--font-weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-tertiary, var(--text-secondary));
    padding: 0.5rem 0.85rem 0.2rem;
}

.move-popover-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.85rem;
    font-size: calc(var(--font-size-controls) * 0.92);
    font-weight: var(--font-weight-medium);
    color: var(--text-primary);
    cursor: pointer;
    border-radius: 0.4rem;
    margin: 0 0.3rem;
    transition:
        background-color 0.12s ease,
        color 0.12s ease;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.move-popover-item.is-focused {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-primary));
    color: var(--text-primary);
}

.move-popover-item.is-current {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary));
    cursor: default;
}

.move-popover-item.is-current.is-focused {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-primary));
}

.move-popover-item.is-danger {
    color: var(--accent-error, var(--accent-danger, #c0392b));
}

.move-popover-item.is-danger.is-focused {
    background: color-mix(in srgb, var(--accent-error, var(--accent-danger, #c0392b)) 14%, var(--background-primary));
    color: var(--accent-error, var(--accent-danger, #c0392b));
}

.move-popover-item.is-danger .move-popover-check {
    color: var(--accent-error, var(--accent-danger, #c0392b));
}

.move-popover-check {
    width: 0.9rem;
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--accent-primary);
    text-align: center;
}

.move-popover-divider {
    height: 1px;
    margin: 0.35rem 0.5rem;
    background: var(--border-primary);
}

/* Marks an entry that opens a submenu rather than acting immediately. */
.move-popover-submenu-caret {
    margin-left: auto;
    padding-left: 0.5rem;
    font-size: 0.7rem;
    color: var(--text-tertiary);
}

/* The current value of an entry that opens a submenu — "3 columns" beside
   "Width", so the menu answers as well as asks. It takes over the trailing
   alignment from whatever follows it, or the row would grow three separate
   right-aligned blocks. */
.move-popover-item-detail {
    margin-left: auto;
    padding-left: 0.5rem;
    font-size: 0.7rem;
    color: var(--text-tertiary);
    white-space: nowrap;
}

.move-popover-item-detail ~ .move-popover-submenu-caret,
.move-popover-item-detail ~ .move-popover-item-key {
    margin-left: 0;
}

/* An entry that is present but cannot act — it still says what it is and, in
   its detail, why it cannot. Removing it would leave the user looking for a
   feature they read about. */
.move-popover-item.is-disabled {
    opacity: 0.55;
    cursor: default;
}

/* ─── Check-mode submenu ─────────────────────────────────────
   Three named modes, each with the sentence that distinguishes it — the same
   copy the health view shows, so the choice reads identically wherever it is
   made. Two-line rows need the alignment and wrapping the flat menu forbids. */
.bookmark-check-mode-menu {
    min-width: 17rem;
    max-width: min(20rem, calc(100vw - 1rem));
}

.bookmark-check-mode-menu .move-popover-item {
    align-items: flex-start;
    white-space: normal;
    overflow: visible;
}

.bookmark-check-mode-menu .move-popover-check {
    margin-top: 0.15rem;
}

.check-mode-option-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.check-mode-option-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/* The accelerator is printed on the option rather than taught elsewhere, so the
   keyboard route is discoverable from the menu itself. */
/* Keyboard hint on a menu row: pushed to the trailing edge so the labels stay
   left-aligned and the keys line up as a column of their own. Same chip as
   .check-mode-option-key, which sits inside a label rather than beside one. */
.move-popover-item-key {
    margin-left: auto;
    padding: 0 0.25rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.2rem;
    font-family: inherit;
    font-size: 0.65rem;
    line-height: 1.4;
    color: var(--text-tertiary);
    white-space: nowrap;
}

.check-mode-option-key {
    padding: 0 0.25rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.2rem;
    font-family: inherit;
    font-size: 0.65rem;
    line-height: 1.4;
    color: var(--text-tertiary);
}

.check-mode-option-body {
    font-size: 0.72rem;
    font-weight: var(--font-weight-normal);
    color: var(--text-secondary);
    white-space: normal;
}

/* On hover the row tints, so the explanation follows rather than staying grey
   against a coloured background. */
.bookmark-check-mode-menu .move-popover-item.is-focused .check-mode-option-body {
    color: inherit;
}

/* ─── Tag popover (Shift+T) ─────────────────────────────────── */
.tag-popover {
    min-width: 13rem;
    max-width: min(18rem, calc(100vw - 1rem));
    outline: none;
}

.tag-popover:focus {
    outline: none;
}

.tag-popover .move-popover-item {
    outline: none;
}

.tag-popover-bookmark-name {
    padding-bottom: 0.35rem;
}

.tag-popover-current-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 0.4rem;
    padding: 0 0.85rem 0.65rem;
}

.tag-popover-current-tags-label {
    font-size: calc(var(--font-size-controls) * 0.72);
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    margin-right: 0.15rem;
}

.tag-popover-current-tags-none {
    font-size: calc(var(--font-size-controls) * 0.88);
    color: var(--text-tertiary, var(--text-secondary));
    font-style: italic;
}

.tag-popover-current-chip {
    font-size: calc(var(--font-size-controls) * 0.78);
    padding: 0.12rem 0.45rem;
}

.tag-popover-empty-hint {
    padding: 0.15rem 0.85rem 0.65rem;
    font-size: calc(var(--font-size-controls) * 0.86);
    color: var(--text-secondary);
    line-height: 1.35;
}

.tag-popover-item-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tag-popover-item-meta {
    flex: 0 0 auto;
    font-size: calc(var(--font-size-controls) * 0.72);
    color: var(--text-tertiary, var(--text-secondary));
    margin-left: auto;
    padding-left: 0.35rem;
}

.move-popover-item.is-current .tag-popover-item-meta {
    color: var(--text-secondary);
}

.date-weather-line {
    font-size: calc(var(--font-size-controls) * 1.6); /* larger for weather */
    color: var(--text-tertiary);
}

/* Add spacing below the date/weather block to separate from page title */
.dashboard-section.section-controls {
    padding-bottom: 1.5rem;
}

.weather-icon {
    display: inline-flex;
    align-items: center;
    margin: 0 0.22rem 0 0.18rem;
    vertical-align: -0.12em;
}

.weather-icon-svg {
    width: 1.05em;
    height: 1.05em;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.weather-text {
    vertical-align: baseline;
}

.title {
    font-size: var(--font-size-title);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-black);
    opacity: 0.8;
    user-select: none;
    color: var(--text-primary);
}

/* Section trail under the view name. Sits in the header's own type scale, not
   the title's, so it reads as orientation rather than a second heading. */
.title-breadcrumb {
    margin: 0.15rem 0 0;
    font-family: var(--font-family-main);
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    user-select: none;
}

.title-breadcrumb[hidden] {
    display: none;
}

.header-actions {
    --header-control-gap: 0.5rem;
    display: flex;
    align-items: center;
    gap: var(--header-control-gap);
    margin-left: auto;
}

/* inbox · health · config — same gap as between page tabs and the pages icon. */
.header-destinations {
    display: flex;
    align-items: center;
    gap: var(--header-control-gap, 0.5rem);
    min-width: 0;
    flex-shrink: 0;
}

.bookmark-link.find-hidden {
    display: none;
}

/* Tag filter view — same dashboard-grid / packed-columns as normal categories */
#dashboard-layout.dashboard-grid.tag-filter-view {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    grid-template-columns: unset;
    row-gap: 0.75rem;
    width: 100%;
    max-width: 100%;
}

.tag-filter-banner {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.55rem;
    padding: 0.35rem 0.5rem 0.65rem;
    flex-shrink: 0;
    width: 100%;
}

.tag-filter-banner-head {
    width: 100%;
}

.tag-filter-bulk-toolbar {
    width: 100%;
}

#dashboard-layout.tag-filter-view .tag-filter-bulk-toolbar {
    margin-bottom: 0;
    padding-bottom: 0;
    border-bottom: none;
}

#dashboard-layout.tag-filter-view .tag-filter-bulk-toolbar .recent-bookmarks-open-btn.modal-button {
    flex: 0 1 auto;
    min-width: min(100%, 10rem);
}

.tag-filter-indicator-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.28rem;
    max-width: 100%;
    min-width: 0;
    padding: 0.22rem 0.55rem;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 55%, var(--border-primary));
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary));
    color: var(--text-primary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.92);
    font-weight: var(--font-weight-semibold);
    line-height: 1.25;
    box-shadow: 0 1px 4px color-mix(in srgb, var(--accent-primary) 18%, transparent);
}

.tag-filter-indicator-prefix {
    color: var(--accent-primary);
    font-weight: var(--font-weight-bold);
}

.tag-filter-indicator-tag {
    color: var(--accent-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tag-filter-indicator-count {
    color: var(--text-secondary);
    font-weight: var(--font-weight-normal);
    font-size: calc(var(--font-size-controls) * 0.85);
    white-space: nowrap;
}

.tag-filter-indicator-count::before {
    content: '·';
    margin-right: 0.28rem;
    opacity: 0.55;
}

/* Shown only while a tag filter is on — updateTagFilterIndicator sets `hidden`
   the rest of the time, and [hidden] would otherwise lose to this rule. */
.tag-filter-indicator {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    min-width: 0;
    max-width: 100%;
}

.tag-filter-indicator[hidden] {
    display: none;
}

.tag-filter-indicator-head {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
    max-width: 100%;
    min-width: 0;
}

.tag-filter-indicator-chips {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    min-width: 0;
    max-width: 100%;
}

.tag-filter-indicator-tag-item {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    max-width: 100%;
    min-width: 0;
}

.tag-filter-indicator-tag-remove {
    flex-shrink: 0;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-tertiary);
    width: 1.25rem;
    height: 1.25rem;
    border-radius: 999px;
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    transition:
        border-color 0.15s ease,
        color 0.15s ease,
        background-color 0.15s ease;
}

.tag-filter-indicator-tag-remove:hover,
.tag-filter-indicator-tag-remove:focus-visible {
    border-color: var(--accent-primary);
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--background-primary) 94%, transparent);
    outline: none;
}

.tag-filter-indicator-summary {
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.85);
    font-weight: var(--font-weight-normal);
    white-space: nowrap;
}

.tag-filter-indicator-summary::before {
    content: '·';
    margin-right: 0.28rem;
    opacity: 0.55;
}

.tag-filter-indicator-chip {
    cursor: pointer;
    transition:
        border-color 0.15s ease,
        background-color 0.15s ease,
        transform 0.15s ease;
}

.tag-filter-indicator-chip:hover,
.tag-filter-indicator-chip:focus-visible {
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 18%, var(--background-secondary));
    outline: none;
    transform: translateY(-1px);
}

.tag-filter-indicator-clear {
    flex-shrink: 0;
    border: 1px solid var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 80%, transparent);
    color: var(--text-secondary);
    width: 1.55rem;
    height: 1.55rem;
    border-radius: 999px;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    transition:
        border-color 0.15s ease,
        color 0.15s ease,
        background-color 0.15s ease;
}

.tag-filter-indicator-clear:hover,
.tag-filter-indicator-clear:focus-visible {
    border-color: var(--accent-primary);
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--background-primary) 94%, transparent);
    outline: none;
}

#dashboard-layout.tag-filter-view .tag-filter-view-body.dashboard-grid {
    width: 100%;
    max-width: 100%;
}

#dashboard-layout.tag-filter-view .tag-filter-view-body.dashboard-grid:not(.packed-columns) {
    width: fit-content;
    max-width: min(100%, var(--dashboard-grid-max-width, 100%));
    margin-inline: auto;
}

.category.tag-filter-chunk {
    gap: 0;
    width: 100%;
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}

/* Equal-width columns: one chunk (10 bookmarks) per dashboard-column */
#dashboard-layout.tag-filter-view .tag-filter-view-body.packed-columns {
    column-gap: var(--gap, 1.5rem);
}

#dashboard-layout.tag-filter-view .tag-filter-view-body.packed-columns .dashboard-column {
    flex: 1 1 0;
    flex-basis: min(
        var(--dashboard-column-max, 300px),
        calc((100% - (var(--packed-columns, 2) - 1) * var(--gap, 1.5rem)) / var(--packed-columns, 2))
    );
    max-width: min(
        var(--dashboard-column-max, 300px),
        calc((100% - (var(--packed-columns, 2) - 1) * var(--gap, 1.5rem)) / var(--packed-columns, 2))
    );
    width: min(
        var(--dashboard-column-max, 300px),
        calc((100% - (var(--packed-columns, 2) - 1) * var(--gap, 1.5rem)) / var(--packed-columns, 2))
    );
    min-width: 0;
}

#dashboard-layout.tag-filter-view .tag-filter-view-body:not(.packed-columns) .category.tag-filter-chunk {
    width: 100%;
    max-width: 100%;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list {
    width: 100%;
    max-width: 100%;
}

/* Tag filter always uses vertical bookmark rows (overrides launcher tiles on parent grid) */
#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list {
    display: grid;
    grid-template-columns: var(--bookmark-lead-col, minmax(1.25rem, max-content)) minmax(0, 1fr) max-content;
    row-gap: 0.5rem;
    flex-direction: unset;
    flex-wrap: unset;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list > * {
    grid-column: 1 / -1;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-link {
    display: grid;
    grid-template-columns: subgrid;
    grid-column: 1 / -1;
    width: 100%;
    max-width: 100%;
    align-items: center;
    padding: 0.5rem var(--bookmark-row-end-pad, 3px) 0.5rem var(--bookmark-row-start-pad, 6px);
    min-height: 1.9rem;
    white-space: nowrap;
    border-radius: 0;
    gap: unset;
    flex-direction: unset;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-link:hover {
    transform: none;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-open::before {
    content: none;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-reorder-handle {
    display: block !important;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-shortcut {
    display: block !important;
    grid-column: 3;
    grid-row: 1;
    text-align: right;
    justify-self: end;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list[data-show-ping="true"] {
    grid-template-columns:
        var(--bookmark-lead-col, minmax(1.25rem, max-content))
        minmax(0, 1fr)
        var(--bookmark-status-col, 3.35em)
        max-content;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list[data-show-ping="true"] .bookmark-link > .status-text {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    align-self: center;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmarks-list[data-show-ping="true"] .bookmark-link > .bookmark-shortcut {
    grid-column: 4;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-open-count {
    display: none !important;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-pin-badge:not(.is-empty),
#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-note-badge:not(.is-empty) {
    display: inline-flex !important;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-lead {
    display: inline-flex;
    justify-content: flex-start;
    align-items: center;
    grid-column: 1;
    grid-row: 1;
    min-height: 1.15em;
    width: auto;
    min-width: 1.15em;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-icon-slot {
    width: auto;
    height: auto;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-icon {
    width: 1.15em;
    height: 1.15em;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk a.bookmark-open {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    grid-column: 2;
    grid-row: 1;
    width: auto;
    min-width: 0;
    flex: unset;
    overflow: hidden;
}

#dashboard-layout.tag-filter-view .tag-filter-chunk .bookmark-text {
    font-size: var(--bookmark-font-size, 1rem);
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
    -webkit-line-clamp: unset;
    -webkit-box-orient: unset;
    line-height: inherit;
}

.empty-state--tag-filter {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 1.5rem 0.75rem;
    color: var(--text-tertiary);
    font-size: var(--font-size-text);
}

.empty-state--tag-filter-text {
    margin: 0;
    line-height: 1.5;
}

.empty-state--tag-filter-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.empty-state--tag-filter-btn {
    appearance: none;
    border: 1px solid var(--border-primary);
    border-radius: var(--header-chip-radius, 999px);
    background: color-mix(in srgb, var(--background-secondary) 55%, transparent);
    color: var(--text-secondary);
    padding: 0.35rem 0.8rem;
    font: inherit;
    font-size: var(--font-size-controls);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.empty-state--tag-filter-btn:hover,
.empty-state--tag-filter-btn:focus-visible {
    color: var(--text-primary);
    border-color: var(--text-primary);
    background: var(--background-secondary);
    outline: none;
}

/* ── Page navigation ─────────────────────────────────────────────────────── */
.page-navigation {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.page-swipe-hint {
    display: none;
}

.page-nav-inbox-host {
    display: flex;
    align-items: center;
}

.page-nav-inbox-host:empty {
    display: none;
}

/* On a touch device wide enough to keep the desktop layout — a tablet, or a
   phone in landscape — the page tabs stay on screen and are tapped with a
   finger. They measured 28x33 there, under the 44px both iOS and Android ask
   for. The phone layout is unaffected: it hides #page-navigation outright and
   has its own 44px rules for the controls it keeps.

   Scoped to coarse pointers rather than applied everywhere, because on a mouse
   these are a dense row of tabs and padding them out to 44px would push the
   later pages off the strip for no gain. */
@media (hover: none) and (pointer: coarse) {
    body:not([data-mobile-layout="true"]) .page-nav-btn {
        min-height: 44px;
        min-width: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        touch-action: manipulation;
    }
}

.page-nav-btn {
    padding: 0.4rem 0.6rem;
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-semibold);
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
    text-align: center;
    position: relative;
}

.page-nav-btn::before,
.page-nav-btn::after {
    content: none;
}

.page-nav-btn:hover {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--background-secondary) 60%, transparent 40%);
}

.page-nav-btn:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.page-nav-btn.active {
    background: var(--background-secondary);
    color: var(--text-primary);
    border-bottom-color: var(--accent-primary);
    font-weight: var(--font-weight-bold);
}

.page-nav-btn.active::before,
.page-nav-btn.active::after {
    content: none;
}

.page-tab-icon {
    margin-right: 0.2em;
    font-style: normal;
    line-height: 1;
}

.page-tab-dot {
    display: inline-block;
    width: 0.45em;
    height: 0.45em;
    border-radius: 50%;
    margin-right: 0.35em;
    vertical-align: middle;
    flex-shrink: 0;
}

/* Page-tab edit popover (top/left set in JS from anchor + viewport) */
.page-tab-popover {
    position: fixed;
    z-index: 1100;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.65rem;
    padding: 0.6rem 0.7rem;
    box-shadow: 0 4px 18px rgba(0,0,0,0.22);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 12rem;
    max-width: min(20rem, calc(100vw - 1rem));
}

.page-tab-popover-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.page-tab-popover-icon {
    width: 2.6rem;
    text-align: center;
    font-size: 1.1em;
    background: var(--background-primary);
    border: 1px solid var(--border-primary);
    border-radius: 0.4rem;
    color: var(--text-primary);
    padding: 0.2rem 0.3rem;
    outline: none;
}
.page-tab-popover-icon:focus { border-color: var(--accent-primary); }

.page-tab-popover-name {
    flex: 1;
    background: var(--background-primary);
    border: 1px solid var(--border-primary);
    border-radius: 0.4rem;
    color: var(--text-primary);
    font: inherit;
    font-size: var(--font-size-controls);
    padding: 0.2rem 0.4rem;
    outline: none;
}
.page-tab-popover-name:focus { border-color: var(--accent-primary); }

.page-tab-color-swatches {
    display: flex;
    gap: 0.3rem;
    flex-wrap: wrap;
}

.page-tab-color-swatch {
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
    transition: border-color 0.12s, transform 0.12s;
}
.page-tab-color-swatch:hover { transform: scale(1.2); }
.page-tab-color-swatch.selected { border-color: var(--accent-primary); }
.page-tab-color-swatch.swatch-none {
    border: 2px solid var(--border-primary);
    background: var(--background-primary) !important;
    position: relative;
}
.page-tab-color-swatch.swatch-none::after {
    content: '✕';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.6rem;
    color: var(--text-secondary);
    line-height: 1;
    pointer-events: none;
}

.page-tab-rename-input {
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--text-primary);
    color: var(--text-primary);
    font: inherit;
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    padding: 0;
    margin: 0;
    width: 8ch;
    min-width: 4ch;
    max-width: 20ch;
    outline: none;
}

@keyframes healthLinkShimmer {
    0% {
        text-shadow: 0 0 0 rgba(var(--accent-primary-rgb, 66, 135, 245), 0);
    }
    50% {
        text-shadow: 0 0 8px rgba(var(--accent-primary-rgb, 66, 135, 245), 0.6);
    }
    100% {
        text-shadow: 0 0 0 rgba(var(--accent-primary-rgb, 66, 135, 245), 0);
    }
}

.health-link a,
.config-link a {
    text-decoration: none;
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-semibold);
    transition: color 0.3s ease;
    color: var(--text-secondary);
}

.health-link a {
    animation: healthLinkShimmer 3s ease-in-out infinite;
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35em;
}

.health-link a:hover,
.config-link a:hover {
    color: var(--text-primary);
}

.health-link a:hover {
    animation: none;
    text-shadow: 0 0 12px rgba(var(--accent-primary-rgb, 66, 135, 245), 0.8);
}

.health-badge {
    position: absolute;
    top: -0.45em;
    right: -0.55em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.15em;
    height: 1.15em;
    padding: 0 0.25em;
    font-size: 0.62em;
    font-weight: var(--font-weight-bold);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    border-radius: 999px;
    color: #fff;
    background: var(--accent-error);
    pointer-events: none;
    z-index: 1;
    box-sizing: border-box;
}

.health-badge-warn {
    background: var(--accent-warning);
    color: var(--text-on-warning, #000);
}

/* Icon variant: pages, health, config, and inbox (in the destination cluster)
   share one chrome; spacing is .header-actions / .header-destinations gap. */
.pages-link--icon,
.health-link--icon,
.config-link--icon {
    margin-left: 0;
}

.pages-link--icon .pages-link-anchor,
.health-link--icon a,
.config-link--icon a,
.header-destinations .page-nav-btn--inbox {
    animation: none;
    display: inline-flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 0.3rem;
    padding: 0.4rem 0.5rem;
    border-radius: var(--layout-radius-sm, 8px);
}

.pages-link--icon .pages-link-anchor {
    font-family: var(--font-family-main);
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    background: transparent;
    border: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    text-decoration: none;
    transition: color 0.3s ease;
}

.pages-link--icon .pages-link-anchor:hover,
.health-link--icon a:hover,
.config-link--icon a:hover,
.header-destinations .page-nav-btn--inbox:hover {
    color: var(--text-primary);
    text-shadow: none;
}

.pages-link--icon .pages-link-anchor:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

/* Active state matched to .page-nav-btn.active: header destinations are the
   same kind of tab as page tabs, so "you are here" must look the same. */
.pages-link--icon .pages-link-anchor,
.health-link--icon a,
.config-link--icon a,
.header-destinations .page-nav-btn--inbox {
    border-bottom: 2px solid transparent;
}

.pages-link--icon .pages-link-anchor.active,
.health-link--icon a.active,
.config-link--icon a.active,
.header-destinations .page-nav-btn--inbox.active {
    background: var(--background-secondary);
    color: var(--text-primary);
    border-bottom-color: var(--accent-primary);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.pages-link--icon .pages-link-icon,
.health-link--icon .health-link-icon,
.config-link--icon .config-link-icon,
.header-destinations .page-nav-btn--inbox .page-tab-icon--svg {
    width: 1.15rem;
    height: 1.15rem;
    display: inline-flex;
    align-items: center;
    color: currentColor;
    flex-shrink: 0;
}

.header-destinations .page-nav-btn--inbox {
    margin-left: 0;
}

/* Inline pill counter after the icon (overrides the absolute superscript dot). */
.health-link--icon .health-badge {
    position: static;
    top: auto;
    right: auto;
    min-width: 1.35rem;
    height: auto;
    padding: 0.1rem 0.4rem;
    font-size: 0.72rem;
    font-weight: var(--font-weight-semibold);
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--accent-error) 40%, transparent);
    background: color-mix(in srgb, var(--accent-error) 18%, transparent);
    color: var(--accent-error);
}

.health-link--icon .health-badge.health-badge-warn {
    border-color: color-mix(in srgb, var(--accent-warning) 45%, transparent);
    background: color-mix(in srgb, var(--accent-warning) 20%, transparent);
    color: var(--accent-warning);
}

/* The down badge shares broken's red — an outage is not a milder thing than a
   dead link. The two are told apart by movement, not hue: only the down state
   pulses the link (see .health-link.is-health-alert). Explicit here so the
   base .health-badge red still applies even beside the warn override above. */
.health-link--icon .health-badge.health-badge-down {
    border-color: color-mix(in srgb, var(--accent-error) 55%, transparent);
    background: color-mix(in srgb, var(--accent-error) 22%, transparent);
    color: var(--accent-error);
}

/* Fired once when the number of down monitors rises, then removed — a header
   ornament that pulsed forever would stop reading as an alert within a day.
   The cooldown and the rise check live in dashboard-visual.js; this is only the
   look of the pulse. */
@keyframes health-alert-pulse {
    0%   { transform: scale(1); }
    30%  { transform: scale(1.18); }
    60%  { transform: scale(0.96); }
    100% { transform: scale(1); }
}

.health-link.is-health-alert .health-link-anchor {
    animation: health-alert-pulse 0.5s cubic-bezier(0.22, 1, 0.36, 1) 3;
    transform-origin: center;
}

/* A quiet ring under the pulse, so a colour-blind or briefly-glanced view still
   catches it. Also removed with the class when the animation ends. */
.health-link.is-health-alert .health-badge {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-error) 30%, transparent);
}

body.no-animations .health-link.is-health-alert .health-link-anchor {
    animation: none !important;
}

@media (prefers-reduced-motion: reduce) {
    .health-link.is-health-alert .health-link-anchor {
        animation: none !important;
    }
}

/* Dashboard Grid */
.dashboard-grid {
    --dashboard-column-min: 250px;
    /* Upper bound a column may grow to. Raised from 300px so that on wide
       screens the columns absorb the available width (fewer, wider, more
       readable columns) instead of staying narrow and leaving large side
       whitespace. Below this width the per-column calc() takes over and the
       columns shrink gracefully toward --dashboard-column-min. */
    --dashboard-column-max: 360px;
    /* The horizontal space between two categories. Named because a wide
       category has to reproduce it between its own inner columns, and packed
       mode sets a different one. */
    --dashboard-column-gap: 1.5rem;
    display: grid;
    row-gap: var(--category-row-gap, 2rem);
    column-gap: var(--dashboard-column-gap);
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    width: 100%;
    max-width: 100%;
}

#dashboard-layout.page-transition {
    animation: dashboardPageFade 200ms ease-out;
}

@keyframes dashboardPageFade {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.dashboard-grid.columns-1 {
    grid-template-columns: 1fr;
}

.dashboard-grid.columns-2 {
    grid-template-columns: repeat(2, 1fr);
}

.dashboard-grid.columns-3 {
    grid-template-columns: repeat(3, 1fr);
}

.dashboard-grid.columns-4 {
    grid-template-columns: repeat(4, 1fr);
}

.dashboard-grid.columns-5 {
    grid-template-columns: repeat(5, 1fr);
}

.dashboard-grid.columns-6 {
    grid-template-columns: repeat(6, 1fr);
}

.dashboard-grid.columns-3:not(.packed-columns) .category,
.dashboard-grid.columns-4:not(.packed-columns) .category,
.dashboard-grid.columns-5:not(.packed-columns) .category,
.dashboard-grid.columns-6:not(.packed-columns) .category {
    width: fit-content;
    max-width: 100%;
}

/* A category set wider than one column.
 *
 * `width: fit-content` above shrinks a category to its content, which is right
 * for a one-column block and wrong for this one: the whole point is to occupy
 * the columns it was given. Same specificity as the rule above and deliberately
 * placed after it, so this wins for the categories that carry the class.
 *
 * Grid only: this is the rule that reaches across grid columns. In packed mode
 * the same width is carried by a band of its own — see the packed block below —
 * and everything from the inner columns down is shared by both.
 */
.dashboard-grid:not(.packed-columns) .category.category--wide {
    grid-column: span var(--category-span, 1);
    width: 100%;
    max-width: 100%;
}

/* Every width, inner columns included, is driven by this one property, so
   putting it back to 1 is enough to undo the whole thing.
 *
 * `!important` because the effective width is written as an inline style at
 * render time and the window can be resized without a re-render — the grid
 * would otherwise still be told to span three columns it no longer has, and
 * spanning past the last column creates implicit ones and scrolls the page
 * sideways. */
@media (max-width: 767px) {
    .dashboard-grid .category.category--wide {
        --category-span: 1 !important;
    }
}

.dashboard-grid.columns-1 .category.category--wide {
    --category-span: 1 !important;
}

/* One category, several columns — and a way to see that at a glance.
 *
 * Two blocks of bookmarks side by side look like two categories. The rule below
 * runs from the left edge of the first column to the right edge of the last,
 * directly under the header, and says that everything beneath it belongs to the
 * name above it — the way a table header rule does.
 *
 * Dropped while the category is collapsed: the body is still in the document
 * with its rows squeezed to nothing, so the rule would be left hanging under a
 * header with visibly nothing under it.
 */
.dashboard-grid .category.category--wide:not([data-collapsed="true"]) .category-body {
    border-top: 1px solid color-mix(in srgb, var(--border-primary) 85%, transparent);
    padding-top: 0.6rem;
}

/* The presets that already draw the category as a card say it themselves — a
   second line inside the box is one line too many. */
.dashboard-grid.layout-cards .category.category--wide:not([data-collapsed="true"]) .category-body,
.dashboard-grid.layout-widgets .category.category--wide:not([data-collapsed="true"]) .category-body {
    border-top: none;
    padding-top: 0;
}

/* The marker in the header: how many columns this category is currently taking.
   Small and quiet — it names what the rule already shows, for the times the
   width alone is ambiguous (a narrow window, two columns of similar length). */
.category-spread-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.15em;
    padding: 0 0.3em;
    border: 1px solid var(--border-secondary);
    border-radius: 0.25rem;
    font-size: 0.7em;
    line-height: 1.5;
    color: var(--text-tertiary);
    white-space: nowrap;
}

/* Wider means more bookmarks side by side, not longer rows.
 *
 * The list is a three-track grid (four with ping times) whose rows span every
 * track, and each row is a subgrid of it — that is what keeps names and status
 * aligned down a column. Repeating the whole track pattern once per column and
 * letting a row span one pattern keeps all of that intact and fills row by row.
 *
 * The launcher and list presets replace the list's display entirely, so these
 * declarations are inert there — their own wrapping already handles the width.
 *
 * Not scoped to either layout: how a wide category arranges its own bookmarks
 * is the same question whether the width came from spanning grid columns or
 * from a packed band.
 */
.dashboard-grid .category.category--wide .bookmarks-list {
    grid-template-columns:
        repeat(var(--category-span, 1),
            var(--bookmark-lead-col, minmax(1.25rem, max-content))
            minmax(0, 1fr)
            var(--bookmark-shortcut-col, max-content));
    /* The grid gap plus the padding two neighbouring categories would each
       have contributed.
     *
     * A run of ordinary categories pads every column on both sides; a wide one
     * is a single box and pads only its outer edges, so its inner columns drift
     * left of the columns above and below by exactly that missing padding. Add
     * it to the gap and the tracks land where a category's content lands.
     *
     * Only the column gap: the row gap belongs to the density setting, whose
     * rule sits further down this file and would otherwise win both. */
    column-gap: calc(var(--dashboard-column-gap, 1.5rem) + 2 * var(--category-inline-pad, 0.5rem));
}

/* The shortcut track is the one intrinsic column in the pattern, and repeating
   the pattern sizes each copy to its own rows: odd rows land in the first
   column, even rows in the second, so the two ended up different widths and
   every column after the first drifted. It is measured across the whole list
   and pinned — see syncWideColumnTracks — which makes the repeats identical
   and the columns line up with the categories above and below. */
.dashboard-grid .category--wide .bookmarks-list[data-show-ping="true"] {
    grid-template-columns:
        repeat(var(--category-span, 1),
            var(--bookmark-lead-col, minmax(1.25rem, max-content))
            minmax(0, 1fr)
            var(--bookmark-status-col, 3.35em)
            var(--bookmark-shortcut-col, max-content));
}

.dashboard-grid .category--wide .bookmarks-list > * {
    grid-column: span 3;
}

.dashboard-grid .category--wide .bookmarks-list[data-show-ping="true"] > * {
    grid-column: span 4;
}

/* The "+ N more" toggle and the empty-category placeholders are not bookmarks:
   they belong under the whole list, not in the first column of it. */
.dashboard-grid .category--wide .bookmarks-list > .category-show-more,
.dashboard-grid .category--wide .bookmarks-list > .empty-state--category,
.dashboard-grid .category--wide .bookmarks-list > .smart-collection-empty {
    grid-column: 1 / -1;
}

/* Packed columns: vertical stacks per column (round-robin), less vertical gap than CSS grid rows.
 *
 * This is the layout packed mode has always had, and it is what runs while no
 * category is wider than one column. A category set wider switches the page to
 * the masonry grid further down — a block cannot reach across flex columns it
 * is sitting inside of.
 */
.dashboard-grid.packed-columns {
    /* The width of a single packed column, written once — the masonry tracks
       below are the same width, so the two shapes line up. */
    --dashboard-column-gap: var(--gap, 1.5rem);
    --packed-column-width: min(
        var(--dashboard-column-max, 300px),
        calc((100% - (var(--packed-columns, 3) - 1) * var(--dashboard-column-gap)) / var(--packed-columns, 3))
    );
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: flex-start;
    justify-content: center;
    column-gap: var(--dashboard-column-gap);
    grid-template-columns: unset;
    width: 100%;
}

.dashboard-grid.packed-columns .dashboard-column {
    display: flex;
    flex-direction: column;
    gap: 3rem;
    flex: 0 0 var(--packed-column-width);
    width: var(--packed-column-width);
    max-width: var(--packed-column-width);
    min-width: 0;
    contain: layout style;
}

/* Packed, with something wider than one column in it.
 *
 * Fixed columns cannot carry a block that reaches across them, and breaking the
 * page into bands left a hole the height of the tallest column beside the wide
 * one. So the page becomes a grid of very short rows: every category spans as
 * many of them as it is tall (set from JS, which is the only place a height is
 * known), and dense flow fills what is left — a wide block takes its columns
 * wherever it fits and the rest carry on beside and beneath it.
 *
 * align-self is what keeps the measuring honest: stretched to its row span, a
 * category would report the height it was given rather than the height it has,
 * and every pass would confirm the previous one.
 */
.dashboard-grid.packed-columns.packed-masonry {
    display: grid;
    grid-template-columns: repeat(var(--packed-columns, 3), var(--packed-column-width));
    grid-auto-rows: 4px;
    grid-auto-flow: row dense;
    column-gap: var(--dashboard-column-gap);
    row-gap: 0;
    justify-content: center;
    align-items: start;
    width: 100%;
}

.dashboard-grid.packed-columns.packed-masonry > .category {
    grid-row: span var(--masonry-span, 1);
    grid-column: span var(--category-span, 1);
    align-self: start;
    min-width: 0;
}

.dashboard-grid.packed-columns .category {
    width: 100%;
    box-sizing: border-box;
}

/* Center column block when the viewport is wider than the configured column count needs */
@media (min-width: 768px) {
    .dashboard-grid:not(.packed-columns):not(.layout-launcher) {
        width: fit-content;
        max-width: min(100%, var(--dashboard-grid-max-width, 100%));
        margin-inline: auto;
        justify-content: center;
    }

    .layout-launcher.packed-columns {
        justify-content: flex-start;
    }
}

.dashboard-grid.layout-compact.packed-columns .dashboard-column {
    gap: 1.5rem;
}

.dashboard-grid.layout-cards.packed-columns .dashboard-column {
    gap: 1.5rem;
}

.dashboard-grid.layout-terminal.packed-columns .dashboard-column {
    gap: 2rem;
}

/* Layout presets */
.dashboard-grid.layout-default {
    row-gap: var(--category-row-gap, 2rem);
    column-gap: 1.5rem;
}

.dashboard-grid.layout-compact {
    row-gap: 1.5rem;
    column-gap: 1rem;
}

.dashboard-grid.layout-compact .category {
    gap: 0.65rem;
}

.dashboard-grid.layout-compact .bookmarks-list {
    gap: 0.3rem;
}

.dashboard-grid.layout-compact .bookmark-link {
    padding: 0.25rem var(--bookmark-row-end-pad, 3px) 0.25rem var(--bookmark-row-start-pad, 6px);
}

.dashboard-grid.density-comfortable .bookmark-link {
    min-height: 2.05rem;
    padding-block: 0.5rem;
}

.dashboard-grid.density-compact .bookmark-link {
    min-height: 1.85rem;
    padding-block: 0.35rem;
}

.dashboard-grid.density-dense .bookmark-link {
    min-height: 1.65rem;
    padding-block: 0.2rem;
    gap: 0.45rem;
}

/* auto: grid class density-auto had no row rules → smart vs normal drifted; align with compact baseline */
.dashboard-grid.density-auto .bookmark-link {
    min-height: 1.85rem;
    padding-block: 0.35rem;
}

/* Inter-row gap scales with density for every bookmarks list (smart + reorderable). */
.dashboard-grid.density-comfortable .bookmarks-list {
    gap: 0.42rem;
}
.dashboard-grid.density-compact .bookmarks-list {
    gap: 0.3rem;
}
.dashboard-grid.density-dense .bookmarks-list {
    gap: 0.18rem;
}
.dashboard-grid.density-auto .bookmarks-list {
    gap: 0.3rem;
}

.dashboard-grid.layout-cards {
    gap: 1.5rem;
}

.dashboard-grid.layout-cards .category {
    background: color-mix(in srgb, var(--background-primary) 92%, var(--text-secondary) 8%);
    border: 1px solid var(--border-primary);
    border-radius: 10px;
    padding: 0.9rem;
}

.dashboard-grid.layout-cards .bookmark-link {
    border: none;
    border-radius: var(--layout-radius-sm, 8px);
    background: transparent;
    padding: var(--cards-pad-block, 0.45rem) 0.55rem;
}

.dashboard-grid.layout-cards .bookmark-open {
    align-items: flex-start;
}

.dashboard-grid.layout-cards .bookmark-text {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-clamp: 2;
    white-space: normal;
}

.dashboard-grid.layout-terminal {
    row-gap: 2rem;
    column-gap: 1.5rem;
}

/* Note badge tooltip */
.bookmark-note-badge {
    position: relative;
    pointer-events: auto;
    cursor: default;
}

.bookmark-note-badge[data-note-tooltip]::after {
    content: attr(data-note-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    right: 0;
    width: max-content;
    max-width: 20rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-primary);
    border-radius: var(--layout-radius-sm, 8px);
    font-size: 0.72rem;
    white-space: normal;
    word-break: break-word;
    text-align: left;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 30;
}

.bookmark-note-badge[data-note-tooltip]:hover::after {
    opacity: 1;
}

/* Inline editor textarea for note */
.bookmark-inline-textarea {
    width: 100%;
    min-height: 3.2rem;
    padding: 0.4rem;
    font-size: 0.9rem;
    resize: vertical;
    font-family: inherit;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-primary);
    color: var(--text-primary);
}

/*
 * Your own note, which is the one line on the card nobody else could have
 * written — and which used to be the faintest thing on it, in the same grey as
 * the site's marketing description.
 */
.bookmark-preview-card-note {
    margin: 0.6rem 0.8rem 0;
    padding: 0.38rem 0.55rem;
    border-left: 2px solid var(--accent-primary, var(--text-secondary));
    border-radius: 0 5px 5px 0;
    background: color-mix(in srgb, var(--accent-primary, var(--text-secondary)) 8%, transparent);
    color: var(--text-primary);
    font-size: calc(var(--font-size-controls) * 0.88);
    line-height: 1.4;
}

.bookmark-preview-card-note-label {
    display: block;
    margin-bottom: 3px;
    font-family: var(--font-family-mono, monospace);
    font-size: calc(var(--font-size-controls) * 0.66);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent-primary, var(--text-secondary));
}

.bookmark-preview-card-note-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

/* Tag autocomplete dropdown (appended to body by tag-autocomplete.js) */
.tag-ac-dropdown {
    position: fixed;
    z-index: 9999;
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    max-height: 14rem;
    overflow-y: auto;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
}

.tag-ac-item {
    padding: 0.35rem 0.6rem;
    font-family: inherit;
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tag-ac-item strong {
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.tag-ac-item:hover,
.tag-ac-item-active {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-primary);
}

/* Preview card tags */
.bookmark-preview-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 0.55rem 0.8rem 0;
}

.dashboard-grid.layout-terminal .category-title-label::before {
    content: '$ ';
}

/* Terminal layout uses "$ " instead of "// "; hide the "//" prefix/handle. */
.dashboard-grid.layout-terminal .category-reorder-handle,
.dashboard-grid.layout-terminal .category-title-prefix {
    display: none;
}

.dashboard-grid.layout-terminal .bookmark-link {
    font-family: "Source Code Pro", monospace;
    letter-spacing: 0.01em;
    gap: 0.35rem;
    padding-left: 1rem;
    white-space: nowrap;
    overflow: hidden;
}

.dashboard-grid.layout-terminal .bookmark-link::before {
    content: '> ';
    opacity: 0.65;
    margin-right: 0;
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    line-height: 1;
    pointer-events: none;
}

.dashboard-grid.layout-terminal .bookmark-open {
    min-width: 0;
    overflow: hidden;
}

.dashboard-grid.layout-terminal .bookmark-text {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dashboard-grid.layout-terminal .bookmark-shortcut {
    width: auto;
}

/* New layout presets: masonry, list, widgets */
.dashboard-grid.layout-masonry {
    gap: 1rem;
}
.dashboard-grid.layout-masonry .category {
    /* allow variable-height cards and denser packing */
    gap: 0.75rem;
}
.dashboard-grid.layout-masonry .bookmark-open {
    align-items: stretch;
}

.dashboard-grid.layout-list {
    gap: 0.6rem;
}
.dashboard-grid.layout-list .category {
    background: transparent;
    border: none;
    padding: 0;
}
.dashboard-grid.layout-list .bookmarks-list {
    display: block;
}
.dashboard-grid.layout-list .bookmark-link {
    grid-template-columns: var(--bookmark-lead-col) minmax(0, 1fr) max-content;
    padding: 0.6rem 0.4rem;
    border-bottom: 1px solid var(--border-primary);
}
.dashboard-grid.layout-list .bookmark-text {
    white-space: normal;
}

.dashboard-grid.layout-widgets {
    gap: 1.5rem;
}
.dashboard-grid.layout-widgets .category {
    background: color-mix(in srgb, var(--background-primary) 94%, var(--text-secondary) 6%);
    border: 1px solid var(--border-primary);
    border-radius: 12px;
    padding: 1rem;
}
.dashboard-grid.layout-widgets .bookmark-link {
    padding: 0.6rem;
    border: none;
    border-radius: var(--layout-radius-sm, 8px);
    background: transparent;
}

/* Preset-driven CSS variables applied via body attributes */
.dashboard-grid {
    gap: var(--gap, 1.5rem);
    font-size: var(--dashboard-font-size, 14px);
}
.dashboard-grid .bookmark-link {
    padding-block: var(--card-padding, 0.5rem);
}
.dashboard-grid .bookmark-text {
    font-size: var(--bookmark-font-size, 1rem);
}

/* Layout presets: set default variable values */
body[data-layout-preset="default"] .dashboard-grid {
    --gap: 3rem;
    --card-padding: 0.9rem;
    --dashboard-font-size: 14px;
    --bookmark-font-size: 1rem;
}
body[data-layout-preset="compact"] .dashboard-grid {
    --gap: 1.5rem;
    --card-padding: 0.45rem;
    --dashboard-font-size: 13px;
    --bookmark-font-size: 0.98rem;
}
body[data-layout-preset="cards"] .dashboard-grid {
    --gap: 1.5rem;
    --card-padding: 0.9rem;
    --dashboard-font-size: 14px;
}
body[data-layout-preset="terminal"] .dashboard-grid {
    --gap: 2rem;
    --card-padding: 0.35rem;
    --dashboard-font-size: 13px;
}
body[data-layout-preset="masonry"] .dashboard-grid {
    --gap: 1rem;
    --card-padding: 0.6rem;
    --dashboard-font-size: 14px;
}
body[data-layout-preset="list"] .dashboard-grid {
    --gap: 0.6rem;
    --card-padding: 0.6rem;
    --dashboard-font-size: 14px;
}
body[data-layout-preset="widgets"] .dashboard-grid {
    --gap: 1.5rem;
    --card-padding: 1rem;
    --dashboard-font-size: 15px;
}
body[data-layout-preset="launcher"] .dashboard-grid {
    --gap: 0.4rem;
    --card-padding: 0.5rem;
    --dashboard-font-size: 14px;
}

/* ─── Launcher layout preset ─────────────────────────────────── */
.dashboard-grid.layout-launcher,
.dashboard-grid.layout-launcher.packed-columns {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

/* With packed-columns: dissolve .dashboard-column wrappers so     */
/* category-sections participate directly in the launcher flex     */
.layout-launcher.packed-columns .dashboard-column {
    display: contents;
}

.layout-launcher .category {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
    padding: 0;
}

.layout-launcher .category-title {
    text-align: left;
    white-space: nowrap;
    padding: 0;
    cursor: default;
}

.layout-launcher .bookmarks-list {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.6rem;
    width: 100%;
}

.layout-launcher .bookmark-link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    width: 88px;
    padding: 0.65rem 0.5rem 0.5rem;
    border-radius: 10px;
    gap: 0.4rem;
    cursor: pointer;
    transition: background 0.12s ease, transform 0.1s ease;
    /* prevent subgrid/grid-row from base styles bleeding in */
    grid-template-columns: none;
    min-height: 0;
    white-space: normal;
}
.layout-launcher .bookmark-link:hover {
    transform: translateY(-2px);
}

/* Stretched-link: transparent ::before overlay covers the whole tile so
   clicking the icon or anywhere on the tile triggers the <a> */
.layout-launcher .bookmark-open::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 10px;
    z-index: 1;
}

.layout-launcher .bookmark-reorder-handle,
.layout-launcher .bookmark-shortcut,
.layout-launcher .bookmark-note-badge,
.layout-launcher .bookmark-pin-badge,
.layout-launcher .bookmark-open-count { display: none !important; }

.layout-launcher .bookmark-lead {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 48px;
    width: 48px;
    flex-shrink: 0;
}
.layout-launcher .bookmark-icon-slot {
    display: flex;
    width: 48px;
    height: 48px;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.layout-launcher .bookmark-icon {
    width: 48px;
    height: 48px;
    object-fit: contain;
}

.layout-launcher .bookmark-open {
    display: flex;
    justify-content: center;
    width: 100%;
    overflow: visible;
    min-width: 0;
    flex: 0 0 auto;
}
.layout-launcher .bookmark-text {
    font-size: 0.7rem;
    text-align: center;
    white-space: normal;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.3;
}

/* ─── Launcher icon sizes ─────────────────────────────────────── */
body[data-launcher-icon-size="small"] .layout-launcher .bookmark-link { width: 68px; }
body[data-launcher-icon-size="small"] .layout-launcher .bookmark-lead { min-height: 32px; width: 32px; }
body[data-launcher-icon-size="small"] .layout-launcher .bookmark-icon-slot { width: 32px; height: 32px; }
body[data-launcher-icon-size="small"] .layout-launcher .bookmark-icon { width: 32px; height: 32px; }

body[data-launcher-icon-size="large"] .layout-launcher .bookmark-link { width: 108px; }
body[data-launcher-icon-size="large"] .layout-launcher .bookmark-lead { min-height: 64px; width: 64px; }
body[data-launcher-icon-size="large"] .layout-launcher .bookmark-icon-slot { width: 64px; height: 64px; }
body[data-launcher-icon-size="large"] .layout-launcher .bookmark-icon { width: 64px; height: 64px; }

/* ─── Launcher dim (search filter) ───────────────────────────── */
.layout-launcher .bookmark-link.launcher-dim {
    opacity: 0.15;
    filter: grayscale(1);
    transition: opacity 0.18s ease, filter 0.18s ease;
    pointer-events: none;
}
.layout-launcher .bookmark-link:not(.launcher-dim) {
    transition: opacity 0.18s ease, filter 0.18s ease;
}

/* ─── Corner FAB layout tokens ───────────────────────────────────────────── */
:root {
    --corner-fab-edge: 1.5rem;
    --corner-fab-height: 2.75rem;
    --corner-fab-gap: 0.4rem;
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    :root {
        --corner-fab-height: 3.35rem;
    }
}

/* ─── What's new FAB ──────────────────────────────────────────────────────── */
.whats-new-btn {
    position: fixed;
    bottom: var(--corner-fab-edge);
    left: var(--corner-fab-edge);
    z-index: 1001;
    padding: 0.62rem 0.72rem;
    border: 1px solid var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 74%, transparent);
    color: var(--accent-primary);
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.65rem;
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
}
.whats-new-btn-icon {
    display: block;
    flex-shrink: 0;
}
.whats-new-btn-update-dot {
    position: absolute;
    top: 0.35rem;
    right: 0.35rem;
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    background: var(--accent-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--background-secondary) 80%, transparent);
    pointer-events: none;
    opacity: 0;
    transform: scale(0);
    transition: opacity 0.2s ease, transform 0.2s ease;
}
.whats-new-btn.has-update-available .whats-new-btn-update-dot {
    opacity: 1;
    transform: scale(1);
    animation: whats-new-update-pulse 1.8s ease-in-out infinite;
}
@keyframes whats-new-update-pulse {
    0%, 100% {
        transform: scale(1);
        box-shadow:
            0 0 0 2px color-mix(in srgb, var(--background-secondary) 80%, transparent),
            0 0 0 0 color-mix(in srgb, var(--accent-primary) 0%, transparent);
    }
    50% {
        transform: scale(1.2);
        box-shadow:
            0 0 0 2px color-mix(in srgb, var(--background-secondary) 80%, transparent),
            0 0 0 5px color-mix(in srgb, var(--accent-primary) 38%, transparent);
    }
}
body.no-animations .whats-new-btn-update-dot {
    animation: none;
    transform: scale(1);
}
.whats-new-btn:hover {
    background: color-mix(in srgb, var(--background-primary) 94%, transparent);
    border-color: var(--accent-primary);
    transform: translateY(-1px);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
}
.whats-new-btn:active {
    transform: translateY(0);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
/* Tooltip */
.whats-new-btn[data-tooltip] {
    position: fixed;
}
.whats-new-btn[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 0;
    white-space: nowrap;
    padding: 0.2rem 0.5rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.3rem;
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.85);
    font-weight: var(--font-weight-normal);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
    z-index: 1001;
}
.whats-new-btn[data-tooltip]:hover::after {
    opacity: 1;
    visibility: visible;
}
@media (pointer: coarse) {
    .whats-new-btn[data-tooltip]::after {
        display: none;
    }
}
/* Linker-dock: what's new naar rechts (tegenover de knoppenbalk) */
body[data-button-position="bottom-left"] .whats-new-btn {
    left: auto;
    right: var(--corner-fab-edge);
}
body[data-button-position="bottom-left"] .whats-new-btn[data-tooltip]::after {
    left: auto;
    right: 0;
}

/* Rechter-dock: what's new expliciet links (tegenover de knoppenbalk) */
body[data-button-position="bottom-right"] .whats-new-btn {
    left: var(--corner-fab-edge);
    right: auto;
}

/* Density overrides (can be combined with layout presets) */
body[data-density-mode="comfortable"] .dashboard-grid {
    --card-padding: 1.2rem;
    --dashboard-font-size: 16px;
    --cards-pad-block: 0.6rem;
}
body[data-density-mode="compact"] .dashboard-grid {
    --card-padding: 0.8rem;
    --dashboard-font-size: 14px;
    --cards-pad-block: 0.45rem;
}
body[data-density-mode="dense"] .dashboard-grid {
    --card-padding: 0.45rem;
    --dashboard-font-size: 13px;
    --cards-pad-block: 0.3rem;
}
/* 'auto' leaves variables to layout + responsive CSS to decide */

/* Vertical space between category rows.
 *
 * Distinct from density above, which sizes the bookmark rows inside a category:
 * this is the gap between the rows of categories themselves, which is what
 * makes a wide page feel empty. The old fixed 3rem is still available as
 * "airy"; the default drops to 2rem, because on a five-column layout 3rem left
 * a visible band of nothing between every row.
 *
 * The variable is read by .dashboard-grid.layout-default and the auto-fit grid;
 * the packed and compact presets keep their own tighter gaps. */
body[data-category-spacing="snug"] {
    --category-row-gap: 1.25rem;
}
body[data-category-spacing="balanced"] {
    --category-row-gap: 2rem;
}
body[data-category-spacing="airy"] {
    --category-row-gap: 3rem;
}


/* Keep terminal rows single-line in dense layouts (e.g. 6 columns). */
.dashboard-grid.layout-terminal .status-text {
    display: none !important;
}

/* Category */
.category {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-width: 0; /* Allow flex items to shrink below content size */
    /* Named, because a wide category has to add it back between its inner
       columns — see the column-gap on its bookmarks list. */
    --category-inline-pad: 0.5rem;
    padding-left: var(--category-inline-pad);
    padding-right: var(--category-inline-pad);
}

.category.animate-enter {
    opacity: 0;
    transform: translateY(8px);
    animation: categoryEnter 140ms ease-out forwards;
    animation-delay: calc(80ms + var(--stagger-index, 0) * 6ms);
}

@keyframes categoryEnter {
    from {
        opacity: 0;
        transform: translateY(8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Centred rather than baseline-aligned, which is what keeps the controls in the
   header from making it taller. On a baseline the "+" sits by its own text
   baseline, and the padding and border below that baseline hang past the line
   the title occupies — 1.4px of extra header, per header, for a button that is
   shorter than the text beside it. Centring aligns boxes instead, so the header
   is simply as tall as its tallest child and a control that fits costs nothing.
   Titles that wrap keep flex-start (see .category-title--multiline): chips
   belong beside the first line there, not centred across both. */
.category-title {
    font-size: var(--font-size-category);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.05em;
    color: var(--text-tertiary);
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    min-width: 0;
}

.category-title-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}

/* The "//" prefix is now a real element that doubles as the drag-reorder handle. */
.category-reorder-handle {
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    white-space: pre;
    opacity: 0.55;
    transition: opacity 0.15s ease;
}

.category-title:hover .category-reorder-handle {
    opacity: 0.85;
}

.category-reorder-handle:hover {
    opacity: 1;
}

.category-reorder-handle:active {
    cursor: grabbing;
}

/* Category being dragged across the grid. */
#dashboard-layout .category.is-draggable {
    opacity: 0.4;
    transform: scale(0.985);
    transition: opacity 0.1s, transform 0.1s;
}

.category-title-trailing {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: baseline;
    flex-shrink: 0;
    white-space: nowrap;
}

.category-title-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.category-title-name--multiline {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-word;
}

.category-title--multiline {
    align-items: flex-start;
}

.category-chevron {
    flex-shrink: 0;
}

/* One button plus a ⋯, not the full set: four sort buttons on every category
   header — and the header repeats per category — took more width than the
   bookmark names beside them. In manual order there is no sort to report, so
   only the ⋯ is left. */
.category-sort-controls {
    display: inline-flex;
    align-items: center;
    gap: 0.2em;
    margin-left: 0.35em;
    flex-shrink: 0;
    opacity: 1;
    pointer-events: auto;
    position: relative;
}

.category-sort-menu-btn {
    font: inherit;
    font-size: 0.68em;
    line-height: 1;
    min-height: 1.45em;
    padding: 0.15em 0.4em;
    border: 1px solid transparent;
    border-radius: 3px;
    background: none;
    color: var(--text-tertiary);
    cursor: pointer;
    opacity: 0.7;
}

.category-sort-menu-btn:hover,
.category-sort-menu-btn:focus-visible,
.category-sort-menu-btn[aria-expanded="true"] {
    opacity: 1;
    color: var(--text-secondary);
    border-color: color-mix(in srgb, var(--text-tertiary) 28%, transparent);
    background: color-mix(in srgb, var(--background-secondary, transparent) 55%, transparent);
}

.category-sort-menu {
    position: absolute;
    top: calc(100% + 0.25em);
    right: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    min-width: 7em;
    padding: 0.2em;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 6px);
    background: var(--background-primary);
    box-shadow: 0 6px 18px color-mix(in srgb, var(--text-primary) 14%, transparent);
}

.category-sort-menu-item {
    font: inherit;
    font-size: 0.68em;
    text-align: left;
    padding: 0.3em 0.5em;
    border: 0;
    border-radius: 3px;
    background: none;
    color: var(--text-secondary);
    cursor: pointer;
    white-space: nowrap;
}

.category-sort-menu-item:hover,
.category-sort-menu-item:focus-visible {
    background: color-mix(in srgb, var(--text-primary) 8%, transparent);
    color: var(--text-primary);
}

.category-sort-menu-item.is-active {
    color: var(--text-primary);
    font-weight: var(--font-weight-bold);
}

.category-sort-menu-item.is-active::before {
    content: '· ';
}

.category-sort-btn {
    font: inherit;
    font-size: 0.68em;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.02em;
    line-height: 1.2;
    min-height: 1.45em;
    padding: 0.15em 0.42em;
    border: 1px solid color-mix(in srgb, var(--text-tertiary) 28%, transparent);
    border-radius: 3px;
    background: color-mix(in srgb, var(--background-secondary, transparent) 55%, transparent);
    color: var(--text-tertiary);
    cursor: pointer;
    opacity: 0.9;
}

.category-sort-btn:hover {
    opacity: 1;
    color: var(--text-secondary);
    border-color: color-mix(in srgb, var(--text-secondary) 35%, transparent);
    background: color-mix(in srgb, var(--hover-bg, currentColor) 35%, transparent);
}

.category-sort-btn.is-active,
.category-sort-controls[data-sort-mode="az"] .category-sort-btn[data-sort-mode="az"],
.category-sort-controls[data-sort-mode="recent"] .category-sort-btn[data-sort-mode="recent"] {
    opacity: 1;
    color: var(--text-primary);
    font-weight: var(--font-weight-bold);
    border-color: color-mix(in srgb, var(--accent-color, currentColor) 65%, transparent);
    background: color-mix(in srgb, var(--accent-color, currentColor) 20%, var(--background-secondary, transparent));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-color, currentColor) 28%, transparent);
    text-decoration: none;
}

.category-sort-controls[data-sort-mode="order"] .category-sort-btn.is-active {
    opacity: 0.9;
    font-weight: var(--font-weight-semibold);
    color: var(--text-tertiary);
    border-color: color-mix(in srgb, var(--text-tertiary) 28%, transparent);
    background: color-mix(in srgb, var(--background-secondary, transparent) 55%, transparent);
    box-shadow: none;
}

.category-sort-btn + .category-sort-btn::before {
    content: none;
}

.bookmarks-list.bookmarks-list--sort-active .bookmark-reorder-handle {
    display: none;
}

/* Manual drag is off while A–Z / Recent sorting owns the order. Signal it: no grab
   affordance, and a not-allowed cursor on a press-drag. A plain click still opens
   the bookmark (the link keeps its own pointer cursor). */
.bookmarks-list.bookmarks-list--sort-active .bookmark-link.reorder-item:active {
    cursor: not-allowed;
}

/* ─── Category collapse — grid-template-rows transition ──────── */
.category-body {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows 260ms ease;
}

.category[data-collapsed="true"] .category-body {
    grid-template-rows: 0fr;
}

.category-body > .bookmarks-list {
    min-height: 0;          /* required: lets the grid row shrink below content height */
    overflow: hidden;
    opacity: 1;
    transition: opacity 200ms ease;
}

.category:not([data-collapsed="true"]) .category-body > .bookmarks-list {
    overflow-x: visible;
}

.category[data-collapsed="true"] .category-body > .bookmarks-list {
    opacity: 0;
}

body.no-animations .category-body {
    transition: none !important;
}
body.no-animations .category-body > .bookmarks-list {
    transition: none !important;
}

.category-title {
    cursor: pointer;
    user-select: none;
}

.category-title--renaming .category-title-label::before {
    content: none;
}

.category-chevron {
    display: inline-block;
    margin-left: 0.4em;
    font-size: 0.7em;
    opacity: 0.35;
    transition: transform 200ms ease, opacity 150ms ease;
    transform: rotate(0deg);
    vertical-align: 0.05em;
    pointer-events: none;
}

.category-chevron::after {
    content: '▾';
}

.category-title:hover {
    background: color-mix(in srgb, var(--hover-bg) 65%, transparent);
    border-radius: var(--layout-radius-sm, 8px);
    padding-left: 0.25rem;
    margin-left: -0.25rem;
}

.category-title:hover .category-chevron {
    opacity: 0.7;
}

.category[data-collapsed="true"] .category-chevron {
    transform: rotate(-90deg);
}

body.no-animations .category-chevron {
    transition: none;
}

.smart-collection-title {
    color: var(--accent-primary);
}

.smart-collection-title .category-chevron {
    color: var(--accent-primary);
}

.smart-collection-why-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.35em;
    padding: 0;
    width: 1.15em;
    height: 1.15em;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 45%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-primary));
    color: var(--accent-primary);
    font-size: 0.62em;
    font-weight: var(--font-weight-bold);
    font-family: var(--font-family-main);
    line-height: 1;
    cursor: help;
    vertical-align: 0.08em;
    opacity: 0.82;
    pointer-events: auto;
    flex-shrink: 0;
}

.smart-collection-why-btn:hover,
.smart-collection-why-btn:focus-visible {
    opacity: 1;
    background: color-mix(in srgb, var(--accent-primary) 16%, var(--background-primary));
    outline: none;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 22%, transparent);
}

.smart-collection-why-popover {
    position: fixed;
    z-index: 200000;
    margin: 0;
    padding: 0.5rem 0.65rem;
    max-width: min(22rem, calc(100vw - 1rem));
    border-radius: 6px;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 40%, var(--border-primary));
    background: var(--background-secondary, #141414);
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-normal);
    line-height: 1.45;
    letter-spacing: normal;
    text-transform: none;
    box-shadow:
        0 10px 28px rgba(0, 0, 0, 0.55),
        0 0 0 1px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

.smart-collection-why-popover[hidden] {
    display: none !important;
}

.smart-collection-why-btn[data-tooltip]::after {
    content: none !important;
    display: none !important;
}

.smart-collection-empty {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0.35rem 0 0.15rem;
    padding: 0.55rem 0.75rem;
    font-size: var(--font-size-controls);
    font-style: normal;
    font-weight: var(--font-weight-semibold);
    line-height: 1.45;
    color: var(--text-secondary);
    opacity: 1;
    border: 1px dashed color-mix(in srgb, var(--border-primary) 80%, transparent);
    border-radius: var(--layout-radius-sm, 8px);
    background: color-mix(in srgb, var(--background-secondary) 50%, transparent);
}

.smart-collection-empty::before {
    content: '○';
    flex-shrink: 0;
    font-size: 0.72em;
    font-weight: var(--font-weight-bold);
    color: var(--text-tertiary);
    opacity: 0.85;
}

.category-rename-input {
    background: transparent;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    color: inherit;
    font: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    padding: 0 0.25em;
    margin: 0;
    width: 12ch;
    min-width: 4ch;
    max-width: 28ch;
    outline: none;
    opacity: 1;
}

.category-rename-input:focus {
    border-color: var(--accent-primary);
}

/* Bookmarks */
.bookmarks-list {
    display: grid;
    grid-template-columns: var(--bookmark-lead-col, minmax(1.25rem, max-content)) minmax(0, 1fr) max-content;
    row-gap: 0.5rem;
    min-width: 0;
    min-height: 2rem;
    width: 100%;
    --bookmark-row-start-pad: 6px;
    --bookmark-row-end-pad: 3px;
    --bookmark-status-col: 3.35em;
}

.bookmarks-list[data-show-ping="true"] {
    grid-template-columns:
        var(--bookmark-lead-col, minmax(1.25rem, max-content))
        minmax(0, 1fr)
        var(--bookmark-status-col, 3.35em)
        max-content;
}

.bookmarks-list > * {
    grid-column: 1 / -1;
}

body.bookmark-dragging .bookmarks-list.reorder-container:not([data-smart-collection="true"]):not(:has(.bookmark-link)) {
    min-height: 3rem;
    position: relative;
}

body.bookmark-dragging .bookmarks-list.reorder-container:not([data-smart-collection="true"]):not(:has(.bookmark-link))::after {
    content: '';
    position: absolute;
    inset: 0;
    border: 1px dashed var(--text-secondary);
    border-radius: var(--layout-radius-sm, 8px);
    opacity: 0.45;
    pointer-events: none;
    transform-origin: top center;
    animation: placeholderIn 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

/* Subtle highlight on all reorder containers while dragging */
body.bookmark-dragging .bookmarks-list.reorder-container:not([data-smart-collection="true"]) {
    border-radius: var(--layout-radius-sm, 8px);
    outline: 1px dashed color-mix(in srgb, var(--text-secondary) 35%, transparent);
    outline-offset: 4px;
}

.bookmark-link {
    --bookmark-lead-col: minmax(1.25rem, max-content);
    display: grid;
    grid-template-columns: subgrid;
    grid-column: 1 / -1;
    grid-auto-rows: auto;
    align-items: center;
    column-gap: 0.6rem;
    text-decoration: none;
    font-size: var(--font-size-bookmark);
    font-weight: var(--font-weight-semibold);
    transition: transform 140ms ease, opacity 120ms ease, color 140ms ease, background 140ms ease;
    position: relative;
    padding: 0.5rem var(--bookmark-row-end-pad, 3px) 0.5rem var(--bookmark-row-start-pad, 6px);
    color: var(--text-primary);
    max-width: 100%;
    min-height: 1.9rem;
}

.bookmark-link.animate-enter {
    opacity: 0;
    transform: translateY(6px);
    animation: bookmarkEnter 130ms ease-out forwards;
    animation-delay: calc(var(--item-index, 0) * 10ms);
}

/* Safety: status updates should never re-hide rows, even if animate-enter lingers. */
.bookmark-link.animate-enter.status-online,
.bookmark-link.animate-enter.status-offline,
.bookmark-link.animate-enter.status-checking {
    animation: none;
    opacity: 1;
    transform: none;
}

@keyframes bookmarkEnter {
    from {
        opacity: 0;
        transform: translateY(6px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Single-row bookmark chrome (cards/list use multiline title; see overrides below) */
.dashboard-grid:not(.layout-cards):not(.layout-list) .bookmark-link:not(.bookmark-inline-editing) {
    white-space: nowrap;
}

/* Keep all row controls on one grid row (ping/shortcut/pin/edit) */
.bookmark-link:not(.bookmark-inline-editing) > * {
    grid-row: 1;
}

a.bookmark-open {
    grid-column: 2;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.3rem;
    color: inherit;
    text-decoration: none;
    overflow: hidden;
    outline: none;
}

a.bookmark-open:hover {
    color: inherit;
}

.bookmark-lead {
    position: relative;
    grid-column: 1;
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.35rem;
    min-width: 1.15em;
    min-height: 1.15em;
    cursor: grab;
}

.bookmarks-list[data-smart-collection="true"] .bookmark-lead {
    cursor: default;
}

.bookmark-reorder-handle {
    position: absolute;
    inset: 0;
    border-radius: 3px;
    cursor: grab;
    touch-action: none;
    background: transparent;
    opacity: 0;
    box-sizing: border-box;
}

.bookmark-link:hover .bookmark-reorder-handle {
    opacity: 0.55;
}

.bookmark-reorder-handle:active {
    cursor: grabbing;
}

.bookmarks-list[data-smart-collection="true"] .bookmark-reorder-handle {
    display: none;
}

.bookmark-link.bookmark-longpress-armed {
    user-select: none;
}

.bookmark-link.bookmark-longpress-armed .bookmark-open {
    user-select: none;
}

.category-title.category-title-longpress-armed {
    user-select: none;
}

/* Inline badge — shared base for pin, note, status */
.bookmark-superscript-badge {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.15em;
    font-size: 0.6rem;
    font-weight: var(--font-weight-semibold);
    line-height: 1;
    padding: 0.18em 0.38em;
    border-radius: 3px;
    background: var(--background-secondary);
    color: var(--text-tertiary);
    border: 1px solid var(--border-secondary);
    white-space: nowrap;
    pointer-events: none;
    user-select: none;
    transition: opacity 120ms ease;
}

.bookmark-pin-badge svg {
    width: 0.7rem;
    height: 0.7rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    display: inline-block;
}

.bookmark-pin-badge.is-empty {
    display: none;
}

.bookmark-note-badge svg {
    width: 0.7rem;
    height: 0.7rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    display: inline-block;
}

.bookmark-note-badge.is-empty {
    display: none;
}

.bookmark-open-count {
    display: none;
}

/* "3 new" — what this page published since the row was last opened. It borrows
   the superscript badge's shape and adds only a hint of the accent: it is worth
   noticing on a scan and never worth reading first. */
.bookmark-fresh-badge {
    margin-left: 0.3em;
    color: var(--accent-primary);
    border-color: color-mix(in srgb, var(--accent-primary) 35%, var(--border-secondary));
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-secondary));
}

.bookmark-fresh-badge.is-empty {
    display: none;
}

.bookmark-tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem;
    margin-left: 0.35rem;
}

.bookmark-tag-chip {
    font-size: 0.68rem;
    line-height: 1;
    padding: 0.15em 0.45em;
    border-radius: 999px;
    background: var(--background-secondary);
    color: var(--text-tertiary);
    border: 1px solid var(--border-secondary);
    white-space: nowrap;
    pointer-events: none;
    user-select: none;
}

.bookmark-shortcut {
    grid-column: 3;
    text-align: right;
    justify-self: end;
    white-space: nowrap;
}

.bookmarks-list[data-show-ping="true"] .bookmark-link > .status-text {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
    align-self: center;
}

.bookmarks-list[data-show-ping="true"] .bookmark-link > .bookmark-shortcut {
    grid-column: 4;
}

.bookmark-shortcut.is-empty {
    display: none;
}


.bookmark-icon-slot {
    width: 1.15em;
    height: 1.15em;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.empty-state--category {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.5rem;
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
}

.empty-state--category-btn {
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 40%, var(--border-primary));
    border-radius: var(--layout-radius-sm, 8px);
    padding: 0.15rem 0.45rem;
    font-size: var(--font-size-controls);
    color: var(--accent-primary);
    cursor: pointer;
    font-family: inherit;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.empty-state--category-btn:hover {
    background: color-mix(in srgb, var(--accent-primary) 18%, transparent);
    border-color: var(--accent-primary);
    color: var(--accent-primary);
}

/* Per-category item cap: rows past the limit are hidden until "show more". */
.bookmark-link.is-overflow-hidden {
    display: none;
}

/* "+ N more" / "show less" toggle — a quiet, secondary control so it doesn't
   compete with the primary "+ bookmark" action. */
.category-show-more {
    display: inline-flex;
    align-items: center;
    margin-top: 0.15rem;
    padding: 0.1rem 0.35rem;
    background: transparent;
    border: none;
    border-radius: var(--layout-radius-sm, 8px);
    font-family: inherit;
    font-size: calc(var(--font-size-controls) * 0.92);
    color: var(--text-tertiary);
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}

.category-show-more:hover,
.category-show-more:focus-visible,
.category-show-more.keyboard-selected {
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
    outline: none;
}

/* Keyboard selection needs to read as "selected" even without :focus-visible,
   which browsers withhold after a click. */
.category-show-more.keyboard-selected {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 45%, transparent);
}

/* Terminal layout: monospace style with > prefix */
.dashboard-grid.layout-terminal .empty-state--category {
    padding-left: 1rem;
    position: relative;
}

.dashboard-grid.layout-terminal .empty-state--category-btn {
    font-family: "Source Code Pro", monospace;
    letter-spacing: 0.01em;
    background: none;
    border-color: color-mix(in srgb, var(--accent-primary) 45%, transparent);
    font-size: inherit;
}

.dashboard-grid.layout-terminal .empty-state--category::before {
    content: '> ';
    position: absolute;
    left: 0;
    opacity: 0.65;
    font-family: "Source Code Pro", monospace;
    pointer-events: none;
}

/* Launcher layout: tile-style add button */
.layout-launcher .empty-state--category {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 88px;
    height: 80px;
    padding: 0.5rem;
    gap: 0.3rem;
}

.layout-launcher .empty-state--category-text {
    display: none;
}

.layout-launcher .empty-state--category-btn {
    width: 88px;
    height: 80px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    border-style: dashed;
    border-width: 1.5px;
    padding: 0;
    font-size: calc(var(--font-size-controls) * 0.85);
    opacity: 0.7;
    transition: opacity 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.layout-launcher .empty-state--category-btn:hover {
    opacity: 1;
    background: color-mix(in srgb, var(--accent-primary) 15%, transparent);
    border-color: var(--accent-primary);
}

.bookmark-icon-letter {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--background-secondary, rgba(128, 128, 128, 0.15));
    color: var(--text-tertiary, currentColor);
    font-size: 0.6em;
    font-weight: 600;
    border-radius: var(--layout-radius-xs, 4px);
    text-transform: uppercase;
    line-height: 1;
    user-select: none;
    pointer-events: none;
    flex-shrink: 0;
}

.bookmark-link.bookmark-inline-editing {
    display: block;
    padding: 0.35rem 0;
    min-height: 0;
    min-width: 0;
}

/* Launcher tiles are narrow glass chips; inline edit needs a full-width panel row. */
.layout-launcher .bookmark-link.bookmark-inline-editing {
    width: auto;
    min-width: min(420px, 90vw);
    max-width: min(520px, 95vw);
    flex: 1 1 100%;
    align-items: stretch;
    padding: 0;
    background: transparent;
    border: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    transform: none;
}

.bookmark-link.bookmark-inline-editing.keyboard-selected {
    background: none;
}

/*
 * Inline edit focus: dim the chrome that is not being edited.
 *
 * Dimmed, not blurred. `filter: blur()` on the neighbouring rows gave each
 * column its own compositing layer, and WebKit paints those in an order that
 * ignores the z-index of unrelated elements — so a tall inline form opened from
 * Health had a blurred neighbouring column painted on top of it, eating every
 * click on its fields. `pointer-events: none` does not help: WebKit hit-tests
 * the composited layer regardless. The same class of bug was fixed the same way
 * in the check-mode popover, by taking the blur out.
 *
 * At 18% opacity the blur was doing almost nothing visually, which is what
 * makes this a straight removal rather than a trade.
 *
 * Do NOT use a body::before backdrop-filter overlay either — it stacks above
 * #dashboard-layout and frosts the form in Safari and Chrome.
 */
body.bookmark-inline-edit-active {
    --inline-edit-panel-bg: var(--background-primary);
    --inline-edit-field-bg: var(--background-secondary);
}

body.bookmark-inline-edit-active .dashboard-section.section-controls,
body.bookmark-inline-edit-active .dashboard-section.section-title,
body.bookmark-inline-edit-active .button-container,
body.bookmark-inline-edit-active #dashboard-layout .category-title,
body.bookmark-inline-edit-active #dashboard-layout .bookmark-link:not(.bookmark-inline-editing) {
    opacity: 0.18;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

body.bookmark-inline-edit-active #dashboard-layout .bookmark-link:not(.bookmark-inline-editing) > * {
    /* No filter here: see above. The row is already at 18% opacity. */
    pointer-events: none;
}

body.bookmark-inline-edit-active #shortcut-search:not(.show) {
    opacity: 0.18;
    pointer-events: none;
    transition: opacity 0.2s ease;
}

body.bookmark-inline-edit-active .bookmark-link.bookmark-inline-editing {
    filter: none;
    opacity: 1;
    pointer-events: auto;
    position: relative;
    z-index: 20;
    isolation: isolate;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    touch-action: manipulation;
}

body.bookmark-inline-edit-active .bookmark-inline-form,
body.bookmark-inline-edit-active .bookmark-inline-form * {
    pointer-events: auto;
    -webkit-user-select: text;
    user-select: text;
}

body.bookmark-inline-edit-active .category .bookmarks-list,
body.bookmark-inline-edit-active .category-body > .bookmarks-list {
    overflow: visible;
    min-height: auto;
}

@media (prefers-reduced-motion: reduce) {
    body.bookmark-inline-edit-active .dashboard-section.section-controls,
    body.bookmark-inline-edit-active .dashboard-section.section-title,
    body.bookmark-inline-edit-active .button-container,
    body.bookmark-inline-edit-active #dashboard-layout .category-title,
    body.bookmark-inline-edit-active #dashboard-layout .bookmark-link:not(.bookmark-inline-editing),
    body.bookmark-inline-edit-active #shortcut-search:not(.show) {
        transition: none;
    }

    body.bookmark-inline-edit-active #dashboard-layout .bookmark-link:not(.bookmark-inline-editing) > * {
        filter: none;
    }
}

body.bookmark-inline-edit-active .bookmark-inline-form {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    filter: none;
    background-color: var(--inline-edit-panel-bg);
    background-image: none;
}

body.bookmark-inline-edit-active #app-modal.modal-overlay.show {
    z-index: 10050;
}

.bookmark-inline-form {
    width: 100%;
    min-width: min(420px, 90vw);
    max-width: none;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.7rem 0.8rem;
    border-radius: 8px;
    /* Solid panel — never rgba modal (see --inline-edit-panel-bg). */
    background-color: var(--inline-edit-panel-bg);
    border: 2px solid var(--border-primary);
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--accent-primary) 22%, var(--border-primary)),
        0 12px 36px color-mix(in srgb, var(--text-primary) 18%, transparent);
    box-sizing: border-box;
    position: relative;
    z-index: 1;
    isolation: isolate;
    animation: inlineEditReveal 180ms ease-out;
}

.bookmark-inline-form .bookmark-inline-input,
.bookmark-inline-form .bookmark-inline-select,
.bookmark-inline-form .bookmark-inline-textarea,
.bookmark-inline-form .bookmark-inline-action-btn,
.bookmark-inline-form .bookmark-inline-icon-preview {
    background-color: var(--inline-edit-field-bg);
    pointer-events: auto;
    user-select: text;
    -webkit-user-select: text;
}

@keyframes inlineEditReveal {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .bookmark-inline-form {
        animation: none;
    }
}

.bookmark-inline-field {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.bookmark-inline-field.bookmark-inline-check {
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
}

/* ─── Flag toggles (pinned / status check / monitor) ─────────────────────────
   One horizontal row of pills instead of three stacked checkbox rows: the flags
   read as a single group, sit near the top where they are easy to find, and cost
   one line instead of three. */

.bookmark-inline-toggles {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
}

/* The real checkbox stays focusable and reachable by screen readers; the pill
   label is the visible control. */
.bookmark-inline-toggle-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.bookmark-inline-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.25rem 0.55rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    background-color: var(--inline-edit-field-bg);
    color: var(--text-secondary);
    font-size: var(--font-size-controls);
    line-height: 1.2;
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.bookmark-inline-toggle svg {
    width: 0.85em;
    height: 0.85em;
    fill: currentColor;
    flex: 0 0 auto;
}

.bookmark-inline-toggle:hover {
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-secondary));
    color: var(--text-primary);
}

.bookmark-inline-toggle-input:checked + .bookmark-inline-toggle {
    border-color: var(--accent-primary);
    background-color: color-mix(in srgb, var(--accent-primary) 14%, var(--inline-edit-field-bg));
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

/* Keyboard focus must stay visible even though the input itself is off-screen. */
.bookmark-inline-toggle-input:focus-visible + .bookmark-inline-toggle {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

/* ─── Availability check mode ────────────────────────────────────────────────
   A segmented control, not two checkboxes: Monitor is a superset of Periodic, so
   only one can be true at a time and the UI should make that structural rather
   than rely on the user knowing it. */

.bookmark-inline-checkmode {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
}

.bookmark-inline-checkmode-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
}

.bookmark-inline-checkmode-option {
    padding: 0.25rem 0.6rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    background-color: var(--inline-edit-field-bg);
    color: var(--text-secondary);
    font-size: var(--font-size-controls);
    line-height: 1.2;
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.bookmark-inline-checkmode-option:hover {
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-secondary));
    color: var(--text-primary);
}

.bookmark-inline-checkmode-input:checked + .bookmark-inline-checkmode-option {
    border-color: var(--accent-primary);
    background-color: color-mix(in srgb, var(--accent-primary) 14%, var(--inline-edit-field-bg));
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.bookmark-inline-checkmode-input:focus-visible + .bookmark-inline-checkmode-option {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.bookmark-inline-checkmode-info {
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    border: 1px solid var(--border-secondary);
    border-radius: 50%;
    background: transparent;
    color: var(--text-tertiary);
    font-size: 0.7rem;
    font-style: italic;
    line-height: 1;
    cursor: pointer;
    flex: 0 0 auto;
}

.bookmark-inline-checkmode-info:hover {
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

/* Explainer modal */
.check-mode-explain-row + .check-mode-explain-row {
    margin-top: 0.9rem;
}

.check-mode-explain-row h4 {
    margin: 0 0 0.2rem;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.check-mode-explain-row p {
    margin: 0;
    color: var(--text-secondary);
    line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
    .bookmark-inline-checkmode-option {
        transition: none;
    }
}

/* Overrides the shared .bookmark-inline-select width:100% (defined later in this
   file) so the interval sits beside the pills instead of claiming its own line —
   the extra specificity is the point, not an accident. */
.bookmark-inline-toggles .bookmark-inline-select.bookmark-inline-toggle-select,
.bookmark-inline-checkmode .bookmark-inline-select.bookmark-inline-toggle-select {
    flex: 0 1 auto;
    width: auto;
    min-width: 0;
    max-width: 100%;
    padding: 0.2rem 0.4rem;
    font-size: var(--font-size-controls);
}

@media (prefers-reduced-motion: reduce) {
    .bookmark-inline-toggle {
        transition: none;
    }
}

.bookmark-inline-label {
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    font-weight: var(--font-weight-semibold);
}

.bookmark-inline-input,
.bookmark-inline-select {
    width: 100%;
    font-family: inherit;
    font-size: var(--font-size-controls);
    padding: 0.25rem 0.4rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-secondary);
    color: var(--text-primary);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
    pointer-events: auto;
    touch-action: manipulation;
    -webkit-user-select: text;
    user-select: text;
}

.bookmark-inline-input:focus,
.bookmark-inline-select:focus {
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 20%, transparent);
}

.bookmark-inline-input.input-error,
.bookmark-inline-input.field-conflict {
    border-color: var(--accent-error);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-error) 20%, transparent);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.bookmark-inline-action-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.bookmark-inline-action-btn.bookmark-inline-save--invalid,
.bookmark-inline-action-btn[aria-disabled="true"] {
    opacity: 0.4;
    cursor: not-allowed;
}

.bookmark-inline-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.25rem;
    align-items: center;
    position: relative;
    z-index: 5;
}

.bookmark-inline-actions .bookmark-inline-action-btn {
    position: relative;
    z-index: 2;
}

.bookmark-inline-hint {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: auto;
    font-size: 0.7rem;
    color: var(--text-tertiary);
    white-space: nowrap;
    pointer-events: none;
    text-align: right;
}

.bookmark-inline-hint kbd {
    font-family: var(--font-family-main);
    font-size: 0.68rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 3px;
    padding: 0.05rem 0.3rem;
    color: var(--text-secondary);
}

.bookmark-inline-conflict {
    display: block;
    font-size: 0.72rem;
    color: var(--accent-error);
    margin-top: 0.2rem;
}

.bookmark-inline-conflict[hidden] {
    display: none;
}

/* ─── Inline create (new page / new category from the form's dropdowns) ───────
   The row takes the select's place inside the same field, so choosing "New …"
   never reflows the form around it. The name input takes the leftover width and
   the two buttons keep their intrinsic size. */

.bookmark-inline-create {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.bookmark-inline-create[hidden] {
    display: none;
}

.bookmark-inline-create .bookmark-inline-create-input {
    flex: 1 1 8rem;
    width: auto;
    min-width: 0;
}

.bookmark-inline-create .bookmark-inline-create-btn {
    flex: 0 0 auto;
}

/* The error spans the whole row rather than squeezing in beside the buttons. */
.bookmark-inline-create .bookmark-inline-conflict {
    flex: 1 0 100%;
    margin-top: 0;
}

/* Sets the create entry apart from the real pages/categories below it. */
.bookmark-inline-new-option {
    font-weight: var(--font-weight-semibold);
}

/* ─── "+ category" — the grid's own add affordance ───────────────────────────
   Sits after the last column rather than inside one: it is not a category, and
   the drag-reorder instances would treat it as one if it were. Dashed and muted
   so it reads as an invitation next to real category headers, not as content.
   `c` does the same thing without it, which is why it may be hidden entirely on
   touch. */

/* Sized and coloured to match .category-sort-btn beside it: this is one more
   control in the same trailing group, not a separate affordance. Squarer than
   the A–Z/Rec chips because it holds a single glyph. */
.category-add-inline-btn {
    font: inherit;
    font-size: 0.68em;
    font-weight: var(--font-weight-semibold);
    line-height: 1.2;
    min-height: 1.45em;
    min-width: 1.45em;
    padding: 0.15em 0.3em;
    margin-left: 0.25em;
    border: 1px solid color-mix(in srgb, var(--text-tertiary) 28%, transparent);
    border-radius: 3px;
    background: color-mix(in srgb, var(--background-secondary, transparent) 55%, transparent);
    color: var(--text-tertiary);
    cursor: pointer;
    opacity: 0.75;
    transition: opacity 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.category-add-inline-btn:hover,
.category-add-inline-btn:focus-visible {
    opacity: 1;
    color: var(--text-secondary);
    border-color: color-mix(in srgb, var(--text-secondary) 35%, transparent);
    outline: none;
}

.category-add-inline-btn[hidden] {
    display: none;
}

/* The name row is hosted by the grid rather than the header the "+" sits in: a
   text input inside a one-line header would overflow the column. It spans the
   grid so it is never squeezed into a single column's width, and only exists
   while naming, so the row it adds is not permanent. */
.bookmark-inline-create.category-add-create {
    grid-column: 1 / -1;
    max-width: 22rem;
    margin-top: 0.75rem;
}

.bookmark-inline-icon-actions {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.3rem;
}

.bookmark-inline-icon-preview {
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--background-primary);
    color: var(--text-tertiary);
    margin-top: 0.25rem;
    overflow: hidden;
}

.bookmark-inline-icon-preview img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.bookmark-inline-icon-preview span {
    font-size: 0.65rem;
    line-height: 1;
}

.bookmark-inline-icon-state {
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
}

.bookmark-inline-action-btn,
.bookmark-inline-create-btn {
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-size: var(--font-size-controls);
    padding: 0.3rem 0.55rem;
    border-radius: var(--layout-radius-sm, 8px);
    cursor: pointer;
}

.bookmark-inline-save,
.bookmark-inline-create-ok {
    border-color: var(--text-secondary);
}

.bookmark-inline-create-btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.bookmark-inline-delete {
    color: var(--text-secondary);
}

@keyframes bookmarkMoveOut {
    0%   { opacity: 1; transform: translateX(0); }
    60%  { opacity: 0.3; transform: translateX(18px); }
    100% { opacity: 0; transform: translateX(32px); max-height: 0; padding: 0; margin: 0; }
}

.bookmark-move-out {
    animation: bookmarkMoveOut 0.32s ease-in forwards;
    overflow: hidden;
    pointer-events: none;
}

.bookmark-inline-delete:hover {
    border-color: var(--text-primary);
    color: var(--text-primary);
}

.bookmarks-list.reorder-container .bookmark-link.is-draggable {
    opacity: 0.45;
    transform: translateX(2px) scale(0.985);
}

.bookmarks-list.reorder-container .bookmark-drop-placeholder {
    height: 1.6rem;
    border: 1px dashed var(--text-secondary);
    border-radius: var(--layout-radius-sm, 8px);
    opacity: 0.65;
    background: color-mix(in srgb, var(--background-primary) 85%, var(--text-secondary) 15%);
    transform-origin: top center;
    animation: placeholderIn 220ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes placeholderIn {
    from {
        opacity: 0;
        transform: scaleY(0.3);
    }
    to {
        opacity: 0.65;
        transform: scaleY(1);
    }
}

.bookmarks-list.reorder-container .bookmark-link.bookmark-move-in {
    animation: bookmarkMoveIn 180ms ease-out;
}

@keyframes bookmarkMoveIn {
    0% {
        opacity: 0.25;
        transform: translateX(8px) scale(0.97);
    }
    100% {
        opacity: 1;
        transform: translateX(0) scale(1);
    }
}

body.no-animations .bookmarks-list.reorder-container .bookmark-link,
body.no-animations .bookmarks-list.reorder-container .bookmark-link.bookmark-move-in,
body.no-animations .bookmarks-list.reorder-container .bookmark-drop-placeholder,
body.no-animations .bookmarks-list.reorder-container::after {
    transition: none;
    animation: none;
}

.bookmark-icon {
    width: 100%;
    height: 100%;
    object-fit: contain;
    flex-shrink: 0;
    -webkit-user-drag: none;
    user-drag: none;
    pointer-events: none;
}

.bookmark-link .bookmark-icon {
    display: block;
}

.category-title .bookmark-icon {
    width: 0.85em;
    height: 0.85em;
    vertical-align: -0.05em;
}

.bookmark-link.smart-recent-promote {
    animation: smartRecentPromote 320ms ease-out;
}

@keyframes smartRecentPromote {
    0% {
        transform: translateY(10px);
        opacity: 0.65;
        box-shadow: 0 0 0 1px var(--accent-success);
    }
    100% {
        transform: translateY(0);
        opacity: 1;
        box-shadow: 0 0 0 0 transparent;
    }
}

.bookmark-text {
    flex: 1;
    min-width: 0; /* Allow text to shrink */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 0.88em;
    line-height: 1.2;
}

/*
 * The link preview card.
 *
 * Three bands in a fixed order — what it is, what it says, what I know about it
 * — each one absent rather than blank when it has nothing to carry. No card-level
 * max-height: the blocks clamp themselves, so nothing disappears without the
 * card being visibly shorter for it.
 */
.bookmark-preview-card {
    position: fixed;
    z-index: 2000;
    display: none;
    width: min(360px, calc(100vw - 24px));
    border-radius: 12px;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.28);
    /* Peek is something to read, not something to reach: it takes no pointer
       events, so it never has to move out of the way of its own cursor. */
    pointer-events: none;
    overflow: hidden;
}

/* `display: flex` and `display: grid` both beat the hidden attribute, and the
   card's bands are laid out with both — so a band that says it is absent has to
   be made absent here, or it draws as an empty stripe. */
.bookmark-preview-card [hidden] {
    display: none !important;
}

.bookmark-preview-card.is-visible {
    display: block;
}

.bookmark-preview-card.is-pinned {
    pointer-events: auto;
    border-color: var(--text-secondary);
}

.bookmark-preview-card:focus-visible {
    outline: 2px solid var(--accent-primary, var(--text-secondary));
    outline-offset: 2px;
}

.bookmark-preview-card-head {
    display: flex;
    gap: 0.55rem;
    align-items: flex-start;
    padding: 0.7rem 0.8rem 0.5rem;
}

.bookmark-preview-card-fav {
    flex: none;
    width: 17px;
    height: 17px;
    margin-top: 2px;
    border-radius: 4px;
    overflow: hidden;
    background: var(--background-primary);
}

.bookmark-preview-card-fav img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.bookmark-preview-card-headtext {
    flex: 1;
    min-width: 0;
}

.bookmark-preview-card-title {
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-bold);
    color: var(--text-primary);
    line-height: 1.25;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}

/* One address, not two: the old card printed the full URL in mono and then its
   hostname on the next line, and neither could be clicked or copied. */
.bookmark-preview-card-domain {
    margin-top: 2px;
    font-family: var(--font-family-mono, monospace);
    font-size: calc(var(--font-size-controls) * 0.8);
    color: var(--text-tertiary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* "Is this link still alive" is the question the rest of the app exists to
   answer, so it is the first thing on the card. */
.bookmark-preview-card-pill {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 7px;
    border-radius: 999px;
    border: 1px solid var(--border-secondary);
    background: rgba(255, 255, 255, 0.03);
    color: var(--text-secondary);
    font-size: calc(var(--font-size-controls) * 0.72);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
}

.bookmark-preview-card-pill::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

.bookmark-preview-card-pill.is-ok {
    color: var(--accent-success, #10B981);
    border-color: color-mix(in srgb, var(--accent-success, #10B981) 40%, transparent);
    background: color-mix(in srgb, var(--accent-success, #10B981) 12%, transparent);
}

.bookmark-preview-card-pill.is-warn {
    color: var(--accent-warning, #F59E0B);
    border-color: color-mix(in srgb, var(--accent-warning, #F59E0B) 40%, transparent);
    background: color-mix(in srgb, var(--accent-warning, #F59E0B) 12%, transparent);
}

.bookmark-preview-card-pill.is-bad {
    color: var(--accent-error, #EF4444);
    border-color: color-mix(in srgb, var(--accent-error, #EF4444) 40%, transparent);
    background: color-mix(in srgb, var(--accent-error, #EF4444) 12%, transparent);
}

.bookmark-preview-card-image-wrap {
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: 158px;
    border-top: 1px solid var(--border-secondary);
    border-bottom: 1px solid var(--border-secondary);
    background: var(--background-primary);
}

.bookmark-preview-card-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bookmark-preview-card-description {
    padding: 0.55rem 0.8rem 0;
    font-size: calc(var(--font-size-controls) * 0.92);
    color: var(--text-secondary);
    line-height: 1.42;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
}

.bookmark-preview-card-empty {
    margin: 0;
    padding: 0.55rem 0.8rem 0;
    font-size: calc(var(--font-size-controls) * 0.88);
    font-style: italic;
    color: var(--text-tertiary);
}

.bookmark-preview-card-facts {
    margin: 0.7rem 0 0;
    padding: 0.5rem 0.8rem 0.6rem;
    border-top: 1px solid var(--border-secondary);
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 3px 12px;
    font-size: calc(var(--font-size-controls) * 0.86);
}

.bookmark-preview-card-facts dt {
    font-family: var(--font-family-mono, monospace);
    font-size: calc(var(--font-size-controls) * 0.74);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    white-space: nowrap;
    line-height: 1.6;
}

.bookmark-preview-card-facts dd {
    margin: 0;
    color: var(--text-secondary);
    line-height: 1.6;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bookmark-preview-card-facts dd b {
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.bookmark-preview-card-facts dd.is-good b { color: var(--accent-success, #10B981); }
.bookmark-preview-card-facts dd.is-warn b { color: var(--accent-warning, #F59E0B); }
.bookmark-preview-card-facts dd.is-bad b { color: var(--accent-error, #EF4444); }

.bookmark-preview-card-facts dd kbd {
    font-family: var(--font-family-mono, monospace);
    font-size: calc(var(--font-size-controls) * 0.78);
    border: 1px solid var(--border-primary);
    border-bottom-width: 2px;
    border-radius: 4px;
    padding: 1px 5px;
    color: var(--text-primary);
}

.bookmark-preview-card-muted {
    color: var(--text-tertiary);
}

/* Only a pinned card has actions, so there is nothing on a peek to aim at. */
.bookmark-preview-card-foot {
    display: flex;
    gap: 4px;
    align-items: center;
    padding: 0.45rem 0.55rem;
    border-top: 1px solid var(--border-secondary);
    background: rgba(0, 0, 0, 0.18);
}

.bookmark-preview-card-action {
    border: 1px solid transparent;
    border-radius: 6px;
    padding: 5px 8px;
    background: none;
    color: var(--text-secondary);
    font-size: calc(var(--font-size-controls) * 0.8);
    cursor: pointer;
}

.bookmark-preview-card-action:hover,
.bookmark-preview-card-action:focus-visible {
    color: var(--text-primary);
    border-color: var(--border-secondary);
    background: rgba(255, 255, 255, 0.04);
    outline: none;
}

.bookmark-preview-card-action:disabled {
    opacity: 0.65;
    cursor: wait;
}

.bookmark-preview-card-esc {
    margin-left: auto;
    font-family: var(--font-family-mono, monospace);
    font-size: calc(var(--font-size-controls) * 0.72);
    color: var(--text-tertiary);
}

/* Bookmark open flash animation */
@keyframes bookmarkFlash {
    0%   { opacity: 0.55; }
    100% { opacity: 0; }
}

.bookmark-link {
    position: relative;
}

.bookmark-link.bookmark-flash::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--accent-primary);
    opacity: 0;
    pointer-events: none;
    animation: bookmarkFlash 380ms ease-out forwards;
}

/* Copy-URL row flash */
@keyframes bookmarkCopyFlash {
    0%   { opacity: 0.45; }
    100% { opacity: 0; }
}

.bookmark-link.bookmark-copy-flash::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--color-success, #4caf7d);
    opacity: 0;
    pointer-events: none;
    animation: bookmarkCopyFlash 500ms ease-out forwards;
}

    body.no-animations .bookmark-link.bookmark-copy-flash::after {
    animation: none;
}

body.no-animations .bookmark-link.bookmark-flash::after {
    animation: none !important;
}

/* Launcher scale-pulse on open */
@keyframes bookmarkPulse {
    0%   { transform: scale(1); }
    30%  { transform: scale(0.95); }
    70%  { transform: scale(1.05); }
    100% { transform: scale(1); }
}

.layout-launcher .bookmark-link.bookmark-pulse {
    animation: bookmarkPulse 260ms ease-out forwards;
}

body.no-animations .layout-launcher .bookmark-link.bookmark-pulse {
    animation: none;
}

/* Keyboard navigation — row highlight lives in theme.css */
.bookmark-link.keyboard-selected {
    position: relative;
}

.layout-launcher .bookmark-link.keyboard-selected,
.layout-launcher .bookmark-link:focus-within {
    outline: none;
    box-shadow: none;
}

.bookmark-shortcut {
    flex-shrink: 0;
    font-family: var(--font-family-mono, monospace);
    font-size: 0.68rem;
    font-weight: var(--font-weight-normal);
    color: var(--text-tertiary);
    background: color-mix(in srgb, var(--background-secondary) 80%, transparent);
    border: 1px solid color-mix(in srgb, var(--border-primary) 65%, transparent);
    border-radius: var(--layout-radius-sm, 8px);
    padding: 0.1em 0.4em;
    line-height: 1.6;
    letter-spacing: 0.03em;
    white-space: nowrap;
    opacity: 1;
}

/* Loading */
.loading {
    text-align: center;
    font-size: var(--font-size-category);
    opacity: 0.7;
    grid-column: 1 / -1;
}

/* Visibility Controls */
body[data-show-title="false"] .title-wrapper {
    display: none;
}

/* Hide config button when showConfigButton is false */
body[data-show-config-button="false"] .config-link {
    display: none;
}

/* Hide cheatsheet button when showCheatSheetButton is false */
body[data-show-cheatsheet-button="false"] .help-button {
    display: none;
}

/* Hide add bookmark button when showAddBookmarkButton is false */
body[data-show-add-bookmark-button="false"] #quick-add-toolbar-btn {
    display: none;
}

/* Hide search button when showSearchButton is false */
body[data-show-search-button="false"] #search-button {
    display: none;
}

/* Hide finders button when showFindersButton is false */
body[data-show-finders-button="false"] .finders-button {
    display: none;
}

/* Hide commands button when showCommandsButton is false */
body[data-show-commands-button="false"] .commands-button {
    display: none;
}

/* Hide recent button when showRecentButton is false */
body[data-show-recent-button="false"] .recent-button {
    display: none;
}

/* Hide fold-all button when showCollapseAllButton is false */
body[data-show-collapse-all-button="false"] #collapse-all-button {
    display: none;
}

/* Collapse the optional secondary toolbar only when all three of its buttons
   are off. Fold-all used to have no setting of its own and rode along with this
   rule, so turning off Recent and Help took it away too — and turning Help back
   on brought it back. Each button now answers only to its own toggle. */
body[data-show-recent-button="false"][data-show-cheatsheet-button="false"][data-show-collapse-all-button="false"] .btn-group-secondary {
    display: none !important;
}

/* Side rail: / tag cloud is a direct .button-container child (not inside secondary group) */
body[data-button-position="side-left"] .button-container > #tag-cloud-toggle-btn.is-eligible {
    display: flex !important;
}

/* Hide bookmark shortcuts when showShortcuts is false */
body[data-show-shortcuts="false"] .bookmark-shortcut {
    display: none;
}

/* Hide pin icon when showPinIcon is false */
body[data-show-pin-icon="false"] .bookmark-pin-badge {
    display: none;
}

/* Hide note icon when showNoteIcon is false */
body[data-show-note-icon="false"] .bookmark-note-badge {
    display: none;
}

/* Terminal layout variants */
body[data-show-shortcuts="false"] .dashboard-grid.layout-terminal .bookmark-link,
body[data-show-pin-icon="false"] .dashboard-grid.layout-terminal .bookmark-link,
body[data-show-note-icon="false"] .dashboard-grid.layout-terminal .bookmark-link {
    gap: 0.28rem;
}

body[data-show-shortcuts="false"][data-show-pin-icon="false"] .dashboard-grid.layout-terminal .bookmark-link {
    gap: 0.24rem;
}

/* Recent bookmarks modal */
.modal.recent-bookmarks-modal {
    max-height: 88vh;
    overflow: hidden;
    max-width: min(52rem, calc(100vw - 2.5rem));
    width: min(52rem, calc(100vw - 2.5rem));
}

.modal.recent-bookmarks-modal .modal-body {
    margin-top: 1rem;
    margin-bottom: 1rem;
}

.recent-bookmarks-modal-toolbar {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.85rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--border-primary);
}

.recent-bookmarks-open-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.recent-bookmarks-open-btn.modal-button {
    flex: 1 1 auto;
    min-width: min(100%, 12rem);
    justify-content: center;
}

.recent-bookmarks-open-hint {
    margin: 0;
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
    line-height: 1.35;
}

.recent-bookmarks-modal-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    max-height: 58vh;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.recent-bookmarks-modal-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.75rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-primary);
    padding: 0.55rem 0.7rem;
    color: var(--text-primary);
    text-decoration: none;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
}

.recent-bookmarks-modal-item:hover {
    transform: none;
    background: color-mix(in srgb, var(--accent-primary) 9%, transparent);
    border-color: color-mix(in srgb, var(--accent-primary) 24%, transparent);
}

.recent-bookmarks-modal-rank {
    flex-shrink: 0;
    min-width: 1.35rem;
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.recent-bookmarks-modal-body {
    display: flex;
    flex-direction: column;
    gap: 0.12rem;
    min-width: 0;
}

.recent-bookmarks-modal-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: var(--font-weight-medium);
}

.recent-bookmarks-modal-detail {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
}

.recent-bookmarks-modal-stats {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.18rem;
    flex-shrink: 0;
}

.recent-bookmarks-modal-recency {
    padding: 0.12rem 0.45rem;
    border-radius: var(--layout-radius-pill, 999px);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 22%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary));
    color: var(--text-secondary);
    font-size: var(--font-size-controls);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.recent-bookmarks-modal-opens {
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.recent-bookmarks-modal-meta {
    flex-shrink: 0;
    color: var(--text-tertiary);
    font-size: var(--font-size-controls);
}

.recent-bookmarks-empty {
    padding: 1.5rem 0.5rem;
    color: var(--text-tertiary);
    font-size: var(--font-size-text);
    text-align: center;
}

/* Dashboard toolbar modals — same placement and chrome as search overlay */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.recent-bookmarks-modal),
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal),
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.whats-new-modal) {
    justify-content: flex-end;
    align-items: center;
    padding: 0 max(1.25rem, 2vw) calc(var(--dashboard-toolbar-stack, 5.75rem) + env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

body:has(#dashboard-layout) #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    width: min(52rem, calc(100vw - 2.5rem));
    max-width: 100%;
    margin: 0;
    max-height: min(70vh, calc(100vh - var(--dashboard-toolbar-stack, 5.75rem) - 2.5rem));
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

/* What's new is narrower than the two it shares the shell with: it is a single
   column of prose, and 52rem ran its lines to ~84 characters. Split out rather
   than folded into the rule above, because the recent-bookmarks list and the
   cheat sheet's two-column key table both still want the width. This selector
   has to repeat the full :has() chain — the shorter .modal.whats-new-modal in
   modal.css loses to it on specificity. */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    width: min(40rem, calc(100vw - 2.5rem));
}

body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.recent-bookmarks-modal) .modal,
body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.keyboard-cheat-sheet-modal) .modal,
body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.whats-new-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.recent-bookmarks-modal),
body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal),
body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.whats-new-modal),
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.recent-bookmarks-modal),
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal),
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.whats-new-modal),
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.recent-bookmarks-modal),
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal),
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.whats-new-modal) {
    justify-content: center;
    padding-bottom: max(2rem, env(safe-area-inset-bottom, 0px));
}

body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body:has(#dashboard-layout)[data-button-position="side-left"] #app-modal.modal-overlay:has(.whats-new-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-left"] #app-modal.modal-overlay:has(.whats-new-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body:has(#dashboard-layout)[data-button-position="bottom-right"] #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    max-height: calc(100vh - 2rem);
}

body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

/* Inbox intro modal — centered above the inbox feed */
body:has(#dashboard-layout.inbox-layout) #app-modal.modal-overlay:has(.inbox-intro-modal) {
    z-index: 13000 !important;
    justify-content: center;
    align-items: center;
    padding: max(1.25rem, 2vw);
    box-sizing: border-box;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    opacity: 1 !important;
    visibility: visible !important;
}

body:has(#dashboard-layout.inbox-layout) #app-modal.modal-overlay.show:has(.inbox-intro-modal) {
    opacity: 1 !important;
    visibility: visible !important;
}

body:has(#dashboard-layout.inbox-layout) #app-modal.modal-overlay:has(.inbox-intro-modal) .modal {
    width: min(40rem, calc(100vw - 2.5rem));
    max-width: 100%;
    margin: 0;
    max-height: min(85vh, calc(100vh - 2.5rem));
    transform: translateY(0) scale(1);
    opacity: 1 !important;
    visibility: visible !important;
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#dashboard-layout.inbox-layout) #app-modal.modal-overlay:has(.inbox-intro-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

/* Page overview modal — centered compact shell */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.page-overview-modal) {
    justify-content: center;
    align-items: center;
    padding: max(1.25rem, 2vw);
    box-sizing: border-box;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

body:has(#dashboard-layout) #app-modal.modal-overlay:has(.page-overview-modal) .modal {
    width: min(22rem, calc(100vw - 2.5rem));
    max-width: 100%;
    margin: 0;
    max-height: min(70vh, calc(100vh - 4rem));
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.page-overview-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.page-overview-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

.recent-bookmarks-skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.recent-bookmarks-skeleton-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.75rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    padding: 0.55rem 0.7rem;
    border-radius: var(--layout-radius-sm, 8px);
}

.recent-bookmarks-skeleton-rank {
    width: 1.35rem;
    height: 0.75em;
    border-radius: 3px;
    background: var(--background-secondary);
}

.recent-bookmarks-skeleton-body {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 0;
}

.recent-bookmarks-skeleton-stats {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.2rem;
}

.recent-bookmarks-skeleton-name,
.recent-bookmarks-skeleton-detail,
.recent-bookmarks-skeleton-recency,
.recent-bookmarks-skeleton-opens {
    display: block;
    border-radius: 3px;
    background: linear-gradient(
        90deg,
        var(--background-secondary) 25%,
        color-mix(in srgb, var(--background-secondary) 60%, var(--text-tertiary) 40%) 50%,
        var(--background-secondary) 75%
    );
    background-size: 200% 100%;
    animation: skeletonShimmer 1.4s ease-in-out infinite;
}

.recent-bookmarks-skeleton-name {
    height: 0.85em;
    width: 72%;
}

.recent-bookmarks-skeleton-detail {
    height: 0.72em;
    width: 42%;
}

.recent-bookmarks-skeleton-recency {
    height: 1.15rem;
    width: 3.25rem;
}

.recent-bookmarks-skeleton-opens {
    height: 0.72em;
    width: 1.5rem;
}

@keyframes skeletonShimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@keyframes nextdashStaleFlash {
    0% {
        box-shadow: 0 0 0 0 var(--accent-primary, rgba(100, 180, 255, 0.65));
    }
    40% {
        box-shadow: 0 0 0 6px rgba(100, 180, 255, 0.15);
    }
    100% {
        box-shadow: 0 0 0 0 transparent;
    }
}

.category.nextdash-stale-flash {
    animation: nextdashStaleFlash 1.1s ease-out 2;
    border-radius: 6px;
}

@keyframes bookmarkDeepLinkFocus {
    0% {
        box-shadow: inset 3px 0 0 var(--accent-primary), 0 0 0 0 color-mix(in srgb, var(--accent-primary) 35%, transparent);
    }
    40% {
        box-shadow: inset 3px 0 0 var(--accent-primary), 0 0 0 6px color-mix(in srgb, var(--accent-primary) 22%, transparent);
    }
    100% {
        box-shadow: inset 3px 0 0 transparent, 0 0 0 0 transparent;
    }
}

.bookmark-link.bookmark-deep-link-focus {
    animation: bookmarkDeepLinkFocus 1.1s ease-out 2;
    border-radius: var(--layout-radius-sm, 8px);
}

body.no-animations .bookmark-link.bookmark-deep-link-focus {
    animation: none;
    box-shadow: inset 3px 0 0 var(--accent-primary);
}

body.no-animations #dashboard-layout.page-transition,
body.no-animations .category.animate-enter,
body.no-animations .bookmark-link.animate-enter,
body.no-animations .bookmark-inline-form,
body.no-animations .bookmark-move-out {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
}

/* ── Quick-add omnibox ──────────────────────────────────────────────────── */

.omnibox-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 0 max(1.25rem, 2vw) calc(var(--dashboard-toolbar-stack, 5.75rem) + env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
    pointer-events: none;
    opacity: 0;
    background: rgba(0, 0, 0, 0.3);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    transition: opacity 0.2s ease-out;
}

.omnibox-overlay.is-visible {
    opacity: 1;
    pointer-events: auto;
}

.omnibox-box {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: min(52rem, calc(100vw - 2.5rem));
    max-width: 100%;
    box-sizing: border-box;
    padding: 0.75rem 1.25rem;
    border: 1px solid color-mix(in srgb, var(--border-primary) 75%, transparent);
    border-radius: var(--layout-radius-md, 12px);
    background: color-mix(in srgb, var(--background-modal) 90%, transparent);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.12);
    /* exit: slide down toward toolbar */
    transform: translateY(10px) scale(0.98);
    opacity: 0;
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

.omnibox-overlay.is-visible .omnibox-box {
    transform: translateY(0) scale(1);
    opacity: 1;
    /* entrance: spring — vertraagt soepel aan het einde */
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

.omnibox-hint {
    font-family: "Source Code Pro", monospace;
    font-size: 0.72rem;
    color: var(--text-tertiary);
    white-space: nowrap;
    flex-shrink: 0;
}

.omnibox-hint::before {
    content: '+';
    color: var(--accent-primary);
    margin-right: 0.4rem;
    font-weight: var(--font-weight-bold);
}

.omnibox-input {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: var(--text-primary);
    font-family: "Source Code Pro", monospace;
    font-size: 0.9rem;
    padding: 0;
    caret-color: var(--accent-primary);
}

.omnibox-input::placeholder {
    color: var(--text-tertiary);
    opacity: 0.5;
}

.omnibox-status {
    font-size: 0.72rem;
    color: var(--text-tertiary);
    white-space: nowrap;
    flex-shrink: 0;
    min-width: 5rem;
    text-align: right;
}

.omnibox-status.is-error {
    color: var(--accent-error);
}

@media (prefers-reduced-motion: reduce) {
    /* Spring drag-and-drop placeholder → instant appear, no scale */
    .bookmark-drop-placeholder,
    .bookmarks-list.reorder-container .bookmark-drop-placeholder {
        animation: none !important;
        opacity: 0.65 !important;
        transform: none !important;
    }
    /* Drag reorder row transitions */
    .bookmarks-list.reorder-container .bookmark-link,
    .bookmarks-list.reorder-container .bookmark-link.bookmark-move-in,
    .bookmarks-list.reorder-container::after {
        transition: none !important;
        animation: none !important;
    }
    /* Skeleton shimmer → static bar */
    .recent-bookmarks-skeleton-name,
    .recent-bookmarks-skeleton-detail,
    .recent-bookmarks-skeleton-recency,
    .recent-bookmarks-skeleton-opens { animation: none !important; }
    /* Page / category / bookmark entrance animations */
    #dashboard-layout.page-transition,
    .category.animate-enter,
    .bookmark-link.animate-enter,
    .bookmark-inline-form { animation: none !important; transform: none !important; opacity: 1 !important; }

    /* Near-zero rather than `none`, matching reduced-motion.css: each of these
       classes is removed again by an `animationend` listener with { once: true }
       (bookmark-move-out in dashboard-inline-edit, bookmark-copy-flash in four
       copy paths, bookmark-pulse in dashboard-bookmark-rows, deep-link-focus in
       dashboard-page-nav). `animation: none` fires no event, so the listener
       never ran and the class stayed on the row for the rest of the session.
       There is nothing to see either way — the animation is over in a frame. */
    .bookmark-move-out { animation-duration: 0.01ms !important; transform: none !important; opacity: 1 !important; }
    .bookmark-link.bookmark-deep-link-focus,
    .bookmark-link.bookmark-copy-flash::after,
    .bookmark-link.bookmark-flash::after,
    .layout-launcher .bookmark-link.bookmark-pulse {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }
    /* Decorative looping, nothing waits on it */
    .health-link a { animation: none !important; }
    /* Promo balloons (entrance + float) */
    .dashboard-feature-promo-balloon,
    .dashboard-g-jump-promo-balloon,
    .dashboard-grid-kbd-promo-balloon,
    .dashboard-smart-collection-promo-balloon,
    .dashboard-search-promo-balloon,
    .dashboard-search-promo-badge { animation: none !important; }
    /* Date popover entrance */
    .date-popover { animation: none !important; }
}



/* ─── Row tag chips ──────────────────────────────────────────────────────── */

/* Inside the link, not a grid column: .bookmark-link is a subgrid whose columns
   line up across every category on the page, so a new column would move every
   row. Same chip as the inbox (.inbox-item-tag) and Config (.config-bm-tag-chip)
   — a tag should look like a tag wherever it is listed. */
.bookmark-tag-strip {
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 0.25rem;
    margin-left: 0.4rem;
    min-width: 0;
    /* Never at the cost of the name: the strip gives way first. */
    flex: 0 1 auto;
    overflow: hidden;
}

.bookmark-tag-chip {
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-secondary);
    font-size: 0.68rem;
    font-weight: var(--font-weight-normal, 400);
    line-height: 1.5;
    white-space: nowrap;
    max-width: 8rem;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bookmark-tag-chip--more {
    font-variant-numeric: tabular-nums;
    opacity: 0.75;
}

/* Terminal and list presets are deliberately dense; a chip there costs more
   than it says, so it drops to text weight instead of a pill. */
.dashboard-grid.layout-terminal .bookmark-tag-chip,
.dashboard-grid.layout-list .bookmark-tag-chip {
    border: 0;
    background: none;
    padding: 0 0.15rem;
    opacity: 0.7;
}

@media (max-width: 720px) {
    /* On a phone the name is the only thing with room. */
    .bookmark-tag-strip { display: none; }
}

/* g is a chord: for three seconds after it, the next key means "top" (g),
   "first pinned" (p) or a category number. Nothing said so, so the only way to
   learn it was to press something and watch. The pill is the key itself, which
   needs no translation. */
body[data-g-chord="armed"]::after {
    content: "g…";
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 60;
    padding: 0.2rem 0.55rem;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 40%, transparent);
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-primary) 14%, var(--background-secondary));
    color: var(--accent-primary);
    font-family: var(--font-family-main);
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    pointer-events: none;
}

/* The key legend under the grid, matching the one health and inbox carry under
   their feeds. Decorative: every key it lists is in the cheat sheet, and the
   rows announce what they do on their own. */
.dashboard-legend {
    display: none;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.3rem 0.9rem;
    margin: 1rem 0 0.25rem;
    font-size: 0.72rem;
    color: var(--text-tertiary);
    opacity: 0.75;
}

/* Only once the keyboard is in use: KeyboardNavigation stamps this at the first
   cursor move and clears it on Enter. Without it the line sat under the grid
   all day — under seven bookmarks, as tall as the thing it explained. No rule
   above it either, which is what made it read as a section of its own. */
body[data-grid-keys="shown"] .dashboard-legend {
    display: flex;
}

.dashboard-legend kbd {
    font-size: 0.7rem;
    padding: 0.05rem 0.32rem;
    border-radius: 0.25rem;
    border: 1px solid var(--border-secondary);
    background: var(--background-secondary);
    color: var(--text-secondary);
}

/* The category icon editor: one field beside the header it changes, the same
   shape the page-tab popover uses. Category.Icon has been stored and rendered
   for a long time with nowhere to set it — eight categories on a page meant
   eight identical ⊣ headers. */
.category-icon-popover {
    position: absolute;
    z-index: 70;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.35rem 0.45rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.4rem;
    background: var(--background-secondary);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.category-icon-input {
    width: 3.2rem;
    padding: 0.15rem 0.35rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.3rem;
    background: var(--background-primary);
    color: var(--text-primary);
    font: inherit;
    text-align: center;
}

.category-icon-clear {
    padding: 0.15rem 0.45rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.3rem;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 0.78rem;
    cursor: pointer;
}

.category-icon-clear:hover,
.category-icon-clear:focus-visible {
    color: var(--accent-primary);
    border-color: color-mix(in srgb, var(--accent-primary) 45%, transparent);
}

/* ── Filter this page (Shift+F) ─────────────────────────────────────────────
   A slim bar above the grid, not a panel: it narrows what is already on screen
   and disappears again with one Escape. Rows and empty categories are hidden
   with a class rather than re-rendered, so the layout, the keyboard cursor and
   any selection survive the filter. */
.grid-filter-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    /* It sits above the grid rather than in it, so it takes the container's
       width whatever shape the grid itself is in. */
    width: 100%;
    box-sizing: border-box;
    margin: 0 0 0.6rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-secondary);
}

.grid-filter-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.85rem;
    padding: 0.15rem 0;
}

.grid-filter-input:focus {
    outline: none;
}

.grid-filter-count {
    color: var(--text-tertiary);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.grid-filter-clear {
    border: 0;
    background: transparent;
    color: var(--text-secondary);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
}

.grid-filter-clear:hover {
    color: var(--text-primary);
}

.bookmark-link.grid-filter-hidden,
.category.grid-filter-empty {
    display: none !important;
}

/* "Publishes, but nothing new" — the quiet half of Fresh, off unless asked for.
   A dot rather than a number, and dimmer than a count: it says this row takes
   part, which is worth a glance and never worth reading. */
.bookmark-fresh-badge.is-quiet {
    color: color-mix(in srgb, var(--accent-primary) 55%, var(--text-tertiary));
    border-color: var(--border-secondary);
    background: transparent;
    letter-spacing: 0;
}

/* ==== css/dashboard-bookmark-row.css ==== */
/* Bookmark row hover / selection — loaded after dashboard.css so layout presets cannot override */

:root {
    --bookmark-row-hover-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 22%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 14%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 6%, var(--background-primary)) 100%
    );
    --bookmark-row-selected-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 30%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 18%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary)) 100%
    );
    --bookmark-row-dimmed-bg: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary)) 0%,
        color-mix(in srgb, var(--accent-primary) 7%, var(--background-primary)) 48%,
        color-mix(in srgb, var(--accent-primary) 3%, var(--background-primary)) 100%
    );
}

.bookmark-link:not(.bookmark-inline-editing) {
    transition:
        background 0.16s ease,
        box-shadow 0.16s ease,
        border-color 0.16s ease,
        color 0.16s ease;
}

body.no-animations .bookmark-link:not(.bookmark-inline-editing) {
    transition: none;
}

/* Status rows: keep extra inset so the left status bar does not crowd favicons. */
.bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link:is(.status-online, .status-offline, .status-checking):not(.bookmark-inline-editing) {
    padding-left: calc(var(--bookmark-row-start-pad, 6px) + 4px);
    border-radius: var(--layout-radius-sm, 8px);
}

.bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--bookmark-row-hover-bg);
    border-radius: var(--layout-radius-sm, 8px);
}

.bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    background: var(--bookmark-row-selected-bg);
}

.bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .bookmark-superscript-badge,
.bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .status-text,
.bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .bookmark-shortcut {
    background: transparent;
    border-color: color-mix(in srgb, var(--accent-primary) 35%, var(--border-secondary));
    color: var(--text-secondary);
}

a.bookmark-open:focus-visible {
    outline: none;
}

/* Status rows: tint idle rows only; hover/selection use default bookmark chrome */
body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-offline-fg, var(--accent-error, #ef4444));
    background: var(--status-offline-bg, color-mix(in srgb, var(--accent-error, #ef4444) 24%, var(--background-primary)));
    box-shadow: inset 3px 0 0 var(--status-offline-bar, var(--accent-error, #ef4444));
}

body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-checking-fg, var(--accent-warning, #f59e0b));
    background: var(--status-checking-bg, color-mix(in srgb, var(--accent-warning, #f59e0b) 16%, var(--background-primary)));
}

/* While the mouse explores bookmarks, soften the stale keyboard selection until the next keyboard move. */
body.bookmark-kbd-selection-dimmed .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) {
    background: var(--bookmark-row-dimmed-bg);
}

body.bookmark-kbd-selection-dimmed .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .bookmark-superscript-badge,
body.bookmark-kbd-selection-dimmed .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .status-text,
body.bookmark-kbd-selection-dimmed .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .bookmark-shortcut {
    background: color-mix(in srgb, var(--background-secondary) 80%, transparent);
    border-color: color-mix(in srgb, var(--border-primary) 65%, transparent);
    color: var(--text-tertiary);
}

/* Status rows — explicit interaction chrome (wins over idle status tint / color-lock) */
.bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link:is(.status-online, .status-offline, .status-checking):is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--bookmark-row-hover-bg);
    box-shadow: none;
}

.bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link:is(.status-online, .status-offline, .status-checking):is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    background: var(--bookmark-row-selected-bg);
}

/* ==== css/modal.css ==== */
/* Modal Styles - EXACT copy of shortcut-search */
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 2000;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
    background: rgba(0, 0, 0, 0.3);
}

.modal-overlay.show {
    opacity: 1;
    visibility: visible;
}

.modal {
    padding: 1.5rem 2rem;
    max-width: 400px;
    width: 90%;
    border: 1px solid color-mix(in srgb, var(--border-primary) 75%, transparent);
    border-radius: var(--layout-radius-md, 12px);
    background: var(--background-modal);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.12);
    overflow: hidden;
    transform: scale(0.98) translateY(8px);
    opacity: 0;
    transition: transform 0.2s ease, opacity 0.2s ease;
}

.modal-overlay.show .modal {
    transform: scale(1) translateY(0);
    opacity: 1;
}

/* 40rem, not the 52rem the cheat sheet uses: this modal is one column of prose,
   and at 52rem its lines ran to ~84 characters — well past the 45–75 where the
   eye still finds the next line reliably. Narrowing is the readability fix, not
   just a size fix. The cheat sheet keeps 52rem because it is a two-column key
   table that needs the width. */
.modal.whats-new-modal {
    max-height: 90vh;
    max-width: min(40rem, calc(100vw - 2.5rem));
    width: min(40rem, calc(100vw - 2.5rem));
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.modal.whats-new-modal .modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.25rem;
}

/* Config → Help: same What's new shell as dashboard toolbar modals (centered) */
body:has(#config-main) #app-modal.modal-overlay:has(.whats-new-modal) {
    justify-content: center;
    align-items: center;
    padding: max(1.25rem, 2vw);
    box-sizing: border-box;
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

body:has(#config-main) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    width: min(40rem, calc(100vw - 2.5rem));
    max-width: 100%;
    margin: 0;
    max-height: min(70vh, calc(100vh - 4rem));
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

body:has(#config-main) #app-modal.modal-overlay.show:has(.whats-new-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#config-main) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

.wn-skeleton-stack {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.5rem;
}

.wn-skeleton-line {
    height: 0.72rem;
    border-radius: 0.25rem;
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--border-primary) 55%, transparent) 0%,
        color-mix(in srgb, var(--border-primary) 25%, transparent) 50%,
        color-mix(in srgb, var(--border-primary) 55%, transparent) 100%
    );
    background-size: 200% 100%;
    animation: wnSkeletonShimmer 1.2s ease-in-out infinite;
}

.wn-skeleton-line--short {
    width: 62%;
}

.wn-lazy-sentinel {
    height: 1px;
    width: 100%;
    pointer-events: none;
}

.wn-load-more-hint {
    margin: 1rem 0 0.5rem;
    font-size: calc(var(--font-size-controls) * 0.9);
    color: var(--text-secondary);
    text-align: center;
}

.wn-empty {
    margin: 0.5rem 0;
    color: var(--text-secondary);
    line-height: 1.55;
}

.wn-release-loading {
    margin: 1rem 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

@keyframes wnSkeletonShimmer {
    0% { background-position: 100% 0; }
    100% { background-position: -100% 0; }
}

body.no-animations .wn-skeleton-line {
    animation: none;
}

/* ── What's New intro block ─────────────────────────────────────── */
/* One column at every width: the release summary reads as a paragraph, and
   side by side with the Ko-fi block it was squeezed into a narrow column while
   the shorter block left dead space beside it.

   The two blocks are fixed overhead on every open, sitting in the most valuable
   space in the modal, so the spacing around them is kept tight — 1rem + 1.5rem
   pushed the first actual release item below the fold. */
.wn-top-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.6rem;
    margin-bottom: 1rem;
    align-items: stretch;
}

@media (max-width: 42rem) {
    .modal.whats-new-modal .modal-header {
        flex-wrap: wrap;
        align-items: flex-start;
    }

    .modal.whats-new-modal .modal-header .wn-update-check-header {
        width: 100%;
        justify-content: flex-start;
    }

    .modal.whats-new-modal .modal-header .wn-update-check-status {
        text-align: left;
        white-space: normal;
    }
}

.wn-feature-lead {
    padding: 0.7rem 0.85rem;
    margin-bottom: 0;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 35%, var(--border-primary));
    border-radius: var(--layout-radius-sm, 8px);
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-secondary));
    min-width: 0;
}

.wn-feature-lead-text {
    margin: 0;
    font-size: var(--font-size-controls);
    color: var(--text-primary);
    line-height: 1.5;
}

.wn-intro {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.7rem 0.85rem;
    margin-bottom: 0;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-secondary);
    min-width: 0;
    box-sizing: border-box;
}

.wn-intro-text {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    line-height: 1.5;
}

.modal.whats-new-modal .modal-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.65rem 1rem;
    flex-wrap: nowrap;
}

.modal.whats-new-modal .modal-header .modal-title {
    flex: 0 0 auto;
    width: auto;
    margin-right: 0;
}

.wn-update-check-header {
    width: auto;
    flex: 1 1 auto;
    flex-shrink: 1;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    gap: 0.65rem;
    min-width: 0;
}

.wn-update-check-header--warn {
    padding: 0.45rem 0.65rem;
    border-radius: var(--layout-radius-sm, 8px);
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-secondary));
    border: 1px solid color-mix(in srgb, var(--accent-primary) 28%, var(--border-primary));
}

.wn-update-check-meta {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 0.35rem 0.45rem;
    min-width: 0;
    flex: 1 1 auto;
}

.wn-feature-lead--skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    justify-content: center;
    background: var(--background-secondary);
    border-color: var(--border-primary);
}

.wn-update-check-dismiss {
    padding: 0.15rem 0.45rem;
    border: none;
    border-radius: 0.35rem;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: calc(var(--font-size-controls) * 0.92);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 0.12em;
}

.wn-update-check-dismiss:hover {
    color: var(--text-primary);
}

.wn-update-check-status {
    margin: 0;
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    line-height: 1.45;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: min(100%, 28rem);
}

.wn-update-check-status--warn { color: var(--accent-primary); }
.wn-update-check-status--ok { color: var(--text-secondary); }
.wn-update-check-status--error { color: var(--accent-error, #d1493f); }
.wn-update-check-status--loading { color: var(--text-secondary); font-style: italic; }

.wn-update-check-link {
    display: inline-block;
    margin-top: 0;
    font-size: var(--font-size-controls);
    color: var(--accent-primary);
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
}

.wn-update-check-link:hover { text-decoration: underline; }

.wn-kofi-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.75rem;
    background: color-mix(in srgb, var(--accent-primary) 13%, transparent);
    color: var(--accent-primary);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 32%, transparent);
    border-radius: 0.4rem;
    text-decoration: none;
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-normal);
    white-space: nowrap;
    transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
    flex-shrink: 0;
}

.wn-kofi-btn:hover {
    background: color-mix(in srgb, var(--accent-primary) 22%, transparent);
    border-color: color-mix(in srgb, var(--accent-primary) 55%, transparent);
    transform: translateY(-1px);
}

.wn-kofi-btn:active {
    transform: translateY(0);
}

.wn-kofi-icon,
.wn-kofi-label {
    position: relative;
    z-index: 1;
    flex-shrink: 0;
}

/* What's new modal — animated donate CTA with twinkling stars */
.wn-kofi-btn--animated {
    position: relative;
    overflow: visible;
    isolation: isolate;
    animation: wn-kofi-btn-glow 3.2s ease-in-out infinite;
}

.wn-kofi-btn--animated::before {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    background: linear-gradient(
        105deg,
        transparent 35%,
        color-mix(in srgb, var(--accent-primary) 28%, transparent) 50%,
        transparent 65%
    );
    background-size: 220% 100%;
    animation: wn-kofi-btn-shimmer 3.2s ease-in-out infinite;
    pointer-events: none;
    z-index: 0;
    opacity: 0.85;
}

.wn-kofi-stars {
    position: absolute;
    inset: -0.55rem -0.75rem;
    pointer-events: none;
    z-index: 2;
}

.wn-kofi-star {
    position: absolute;
    line-height: 1;
    color: color-mix(in srgb, var(--accent-primary) 88%, #fff 12%);
    text-shadow: 0 0 6px color-mix(in srgb, var(--accent-primary) 45%, transparent);
    opacity: 0;
    transform: scale(0.5) rotate(0deg);
    animation: wn-kofi-star-twinkle 2.6s ease-in-out infinite;
}

.wn-kofi-star::before {
    content: '★';
    display: block;
    font-size: 0.62rem;
}

.wn-kofi-star:nth-child(1) {
    top: -0.1rem;
    left: 6%;
    animation-delay: 0s;
}

.wn-kofi-star:nth-child(2) {
    top: -0.35rem;
    right: 10%;
    animation-delay: 0.65s;
}

.wn-kofi-star:nth-child(2)::before {
    content: '✦';
    font-size: 0.5rem;
}

.wn-kofi-star:nth-child(3) {
    bottom: -0.15rem;
    left: 18%;
    animation-delay: 1.3s;
}

.wn-kofi-star:nth-child(3)::before {
    font-size: 0.48rem;
}

.wn-kofi-star:nth-child(4) {
    bottom: 0;
    right: 4%;
    animation-delay: 1.95s;
}

.wn-kofi-star:nth-child(4)::before {
    content: '✦';
    font-size: 0.54rem;
}

@keyframes wn-kofi-star-twinkle {
    0%, 100% {
        opacity: 0;
        transform: scale(0.45) rotate(-12deg);
    }
    45%, 55% {
        opacity: 1;
        transform: scale(1.15) rotate(10deg);
    }
}

@keyframes wn-kofi-btn-glow {
    0%, 100% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-primary) 0%, transparent);
    }
    50% {
        box-shadow: 0 0 0.65rem 0.12rem color-mix(in srgb, var(--accent-primary) 32%, transparent);
    }
}

@keyframes wn-kofi-btn-shimmer {
    0%, 100% {
        background-position: 120% 0;
    }
    50% {
        background-position: -20% 0;
    }
}

.wn-kofi-btn--animated:hover {
    animation: none;
    box-shadow: 0 0 0.75rem 0.15rem color-mix(in srgb, var(--accent-primary) 38%, transparent);
}

.wn-kofi-btn--animated:hover .wn-kofi-star {
    animation-duration: 1.4s;
}

body.no-animations .wn-kofi-btn--animated,
body.no-animations .wn-kofi-btn--animated::before,
body.no-animations .wn-kofi-star {
    animation: none;
}

body.no-animations .wn-kofi-btn--animated {
    box-shadow: 0 0 0.5rem 0.1rem color-mix(in srgb, var(--accent-primary) 28%, transparent);
}

body.no-animations .wn-kofi-star {
    opacity: 0.75;
    transform: scale(1);
}

/* ── What's New release blocks ─────────────────────────────────── */
.wn-release {
    margin-bottom: 1.75rem;
    padding-left: 0.9rem;
    border-left: 2px solid var(--accent-primary);
}
.wn-release:last-child { margin-bottom: 0; }

.wn-release-header {
    display: flex;
    align-items: baseline;
    flex-wrap: nowrap;
    gap: 0.55rem;
    margin-bottom: 0.9rem;
}
.wn-release-tag {
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    color: var(--accent-primary);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 38%, transparent);
    background: color-mix(in srgb, var(--accent-primary) 9%, transparent);
    padding: 0.1rem 0.42rem;
    white-space: nowrap;
    flex-shrink: 0;
}
.wn-release-date {
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    white-space: nowrap;
}

/* Sections get more air than items do, so the four groups read as groups while
   scrolling. The extra height that costs is more than paid back by the narrower
   column: shorter lines mean fewer wrapped rows per item. */
.wn-section { margin-bottom: 1.1rem; }
.wn-section:last-child { margin-bottom: 0; }

.wn-section-title {
    font-size: var(--font-size-category);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: 0.45rem;
    letter-spacing: 0.01em;
}

.wn-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 0.55rem;
}
.wn-item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    /* 1.5 rather than 1.55: at ~63 characters a line needs less leading than it
       did at ~84 to stay trackable. */
    line-height: 1.5;
}
.wn-item-text {
    flex: 1;
    font-size: var(--font-size-text);
    color: var(--text-secondary);
}
.wn-item-text strong { color: var(--text-primary); }
.wn-item-text code {
    font-family: var(--font-family-main);
    font-size: 0.88em;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    padding: 0.05rem 0.28rem;
    color: var(--text-primary);
}
.wn-badge {
    flex-shrink: 0;
    font-size: 0.68em;
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 0.12rem 0.38rem;
    border: 1px solid;
    margin-top: 0.18rem;
    white-space: nowrap;
}
.wn-badge-new {
    color: var(--accent-success);
    border-color: color-mix(in srgb, var(--accent-success) 40%, transparent);
    background: color-mix(in srgb, var(--accent-success) 9%, transparent);
}
.wn-badge-fix {
    color: var(--text-tertiary);
    border-color: var(--border-primary);
    background: var(--background-secondary);
}

/* "New shortcuts" section — tinted with --accent-warning so it reads as a
   distinct kind of content next to the green new / grey fix rundown. */
.wn-section-keys {
    border-left: 3px solid color-mix(in srgb, var(--accent-warning) 55%, transparent);
    background: color-mix(in srgb, var(--accent-warning) 6%, transparent);
    padding: 0.6rem 0.75rem 0.65rem;
    border-radius: 0 var(--layout-radius-sm, 6px) var(--layout-radius-sm, 6px) 0;
}

.wn-section-keys .wn-section-title {
    color: var(--accent-warning);
}

.wn-item-keys {
    align-items: baseline;
}

.wn-keycap {
    flex-shrink: 0;
    font-family: var(--font-family-main);
    font-size: 0.82em;
    font-weight: var(--font-weight-semibold);
    color: var(--accent-warning);
    background: color-mix(in srgb, var(--accent-warning) 12%, var(--background-primary));
    border: 1px solid color-mix(in srgb, var(--accent-warning) 45%, transparent);
    border-radius: var(--layout-radius-sm, 5px);
    padding: 0.1rem 0.4rem;
    white-space: nowrap;
    min-width: 2.2rem;
    text-align: center;
}

.modal.keyboard-cheat-sheet-modal {
    max-width: min(52rem, calc(100vw - 2.5rem));
    width: min(52rem, calc(100vw - 2.5rem));
    margin: auto;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    padding: 1rem 1.2rem;
}

.modal.keyboard-cheat-sheet-modal .modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.modal.inbox-intro-modal {
    max-width: min(40rem, calc(100vw - 2.5rem));
    width: min(40rem, calc(100vw - 2.5rem));
    margin: auto;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    padding: 1rem 1.2rem;
}

.modal.inbox-intro-modal .modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.25rem;
}

.inbox-intro-content {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.inbox-intro-hero {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    padding: 0.85rem 0.95rem;
    border-radius: var(--layout-radius-sm, 8px);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 28%, var(--border-primary));
    border-left: 3px solid var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-secondary));
}

.inbox-intro-hero-icon {
    flex-shrink: 0;
    font-size: 1.65rem;
    line-height: 1;
    margin-top: 0.05rem;
}

.inbox-intro-hero-text {
    min-width: 0;
}

.inbox-intro-lead {
    margin: 0;
    color: var(--text-primary);
    font-size: var(--font-size-controls);
    line-height: 1.55;
}

.inbox-intro-section {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin: 0;
    padding: 0;
}

.inbox-intro-section-title {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    font-size: var(--font-size-category);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    letter-spacing: 0.01em;
}

.inbox-intro-section-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.35rem;
    height: 1.35rem;
    font-size: 0.95rem;
    line-height: 1;
    flex-shrink: 0;
}

.inbox-intro-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}

.inbox-intro-item {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.55rem 0.65rem;
    border-radius: var(--layout-radius-sm, 8px);
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    line-height: 1.5;
}

.inbox-intro-item-icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.65rem;
    height: 1.65rem;
    border-radius: 0.4rem;
    font-size: 1rem;
    line-height: 1;
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-primary));
    border: 1px solid color-mix(in srgb, var(--accent-primary) 18%, var(--border-primary));
}

.inbox-intro-item-text {
    flex: 1;
    min-width: 0;
    font-size: var(--font-size-text);
    color: var(--text-secondary);
}

.inbox-intro-item-text strong {
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.inbox-intro-item-text code,
.inbox-intro-item-text kbd,
.inbox-intro-shortcut code,
.inbox-intro-shortcut kbd {
    font-family: var(--font-family-main);
    font-size: 0.88em;
    background: var(--background-primary);
    border: 1px solid var(--border-primary);
    padding: 0.05rem 0.3rem;
    border-radius: 0.25rem;
    color: var(--text-primary);
}

.inbox-intro-shortcuts {
    display: grid;
    gap: 0.45rem;
}

.inbox-intro-shortcut {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.65rem;
    border-radius: var(--layout-radius-sm, 8px);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 22%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 6%, var(--background-secondary));
    font-size: var(--font-size-text);
    color: var(--text-secondary);
    line-height: 1.45;
}

.inbox-intro-shortcut kbd,
.inbox-intro-shortcut code {
    flex-shrink: 0;
    font-weight: var(--font-weight-semibold);
}

.modal.inbox-intro-modal .modal-header .modal-title {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

/* Page overview — compact centered modal (dashboard header pages button) */
.modal.page-overview-modal {
    max-width: min(22rem, calc(100vw - 2.5rem));
    width: min(22rem, calc(100vw - 2.5rem));
    margin: auto;
    max-height: min(70vh, calc(100vh - 4rem));
    overflow: hidden;
    display: flex;
    flex-direction: column;
    padding: 1rem 1.15rem;
}

.modal.page-overview-modal .modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-right: 0.2rem;
    /* The last child ends flush with this scroll box, and overflow clipping eats
       the final pixel row — the name input's bottom border went missing. A pixel
       of padding gives that border somewhere to land. */
    padding-bottom: 1px;
    margin-top: 0.55rem;
    margin-bottom: 0.25rem;
}

.page-overview-modal-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    max-height: min(52vh, 24rem);
    overflow-y: auto;
}

.page-overview-modal-item {
    margin: 0;
    padding: 0;
}

.page-overview-modal-link {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    margin: 0;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-primary);
    cursor: pointer;
    font: inherit;
    font-size: var(--font-size-text);
    text-align: left;
    color: var(--text-primary);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.page-overview-modal-link:hover,
.page-overview-modal-link:focus-visible,
.page-overview-modal-item.is-focused .page-overview-modal-link {
    background: color-mix(in srgb, var(--accent-primary) 9%, transparent);
    border-color: color-mix(in srgb, var(--accent-primary) 24%, transparent);
    outline: none;
}

.page-overview-modal-item.is-current .page-overview-modal-name {
    color: var(--accent-primary);
    font-weight: var(--font-weight-semibold);
}

.page-overview-modal-lead {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    min-width: 1.5rem;
    justify-content: flex-end;
}

.page-overview-modal-num {
    font-size: 0.78em;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
}

.page-overview-modal-body {
    min-width: 0;
}

.page-overview-modal-name {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.page-overview-modal-count {
    font-size: 0.82em;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ─── "New page" — the overlay's one action ──────────────────────────────────
   It borrows .page-overview-modal-link for its shape so it lines up with the
   pages above, and is set apart by the rule above it and a muted, dashed
   border: a thing to do, not a page to go to. */

.page-overview-modal-actions {
    margin-top: 0.55rem;
    padding-top: 0.55rem;
    border-top: 1px solid var(--border-primary);
}

.page-overview-modal-new {
    border-style: dashed;
    color: var(--text-secondary);
}

.page-overview-modal-new[hidden] {
    display: none;
}

.page-overview-modal-plus {
    font-size: 1em;
    color: var(--text-secondary);
}

/* The shortcut hint sits where a page shows its bookmark count. */
.page-overview-modal-hintkey {
    opacity: 0.75;
}

/* The name row takes the button's place inside the same action block, so
   opening it does not change the modal's height. */
.page-overview-modal-actions .bookmark-inline-create {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
}

.page-overview-modal-actions .bookmark-inline-create[hidden] {
    display: none;
}

.page-overview-modal-actions .bookmark-inline-create-input {
    flex: 1 1 8rem;
    min-width: 0;
    padding: 0.4rem 0.5rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-primary);
    color: var(--text-primary);
    font: inherit;
    font-size: var(--font-size-controls);
}

/* Colour and size come from .bookmark-inline-conflict in dashboard.css; only
   the full-width placement in this flex row belongs here. */
.page-overview-modal-actions .bookmark-inline-conflict {
    flex: 1 0 100%;
    margin-top: 0;
}

/* Fix hidden attribute override */
.modal-overlay[hidden] {
    display: none !important;
    opacity: 0 !important;
    visibility: hidden !important;
}

.modal-header {
    display: flex;
    align-items: center;
    font-size: var(--font-size-bookmark);
    font-weight: var(--font-weight-semibold);
    justify-content: flex-start;
}

.modal-title {
    margin-right: 0.5rem;
    color: var(--text-primary);
}

.modal-body {
    margin-top: 1.5rem;
    margin-bottom: 1.5rem;
}

/* New bookmark modal textarea */
.new-bookmark-textarea {
    width: 100%;
    min-height: 4rem;
    padding: 0.5rem;
    font-size: 0.95rem;
    resize: vertical;
    margin-top: 0.35rem;
}

.modal-text {
    min-width: 2ch;
    color: var(--text-primary);
    display: block;
}

/* The existing bookmark inside the "already saved" dialog: a link, because
   knowing where a copy is only helps if you can go there from here. */
.duplicate-existing {
    margin-top: 0.6rem;
}

.duplicate-existing a {
    color: var(--accent-primary);
    word-break: break-word;
}

.duplicate-existing-hint {
    display: block;
    font-size: 0.75rem;
    color: var(--text-secondary);
}

.danger {
    color: var(--accent-error);
    font-weight: var(--font-weight-bold);
}

.modal-actions {
    display: flex;
    flex-direction: row;
    gap: 1rem;
    justify-content: center;
    align-items: center;
}

.modal-button {
    padding: 0.5rem 1rem;
    cursor: pointer;
    transition: all 0.3s ease;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 6px);
    background: transparent;
    text-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    min-width: 0;
    color: var(--text-primary);
    font-family: var(--font-family-main);
    
    /* Remove tap highlight on mobile */
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.modal-button:hover,
.modal-button.selected {
    color: var(--text-primary);
    transform: translateX(4px);
}

.modal-button-prefix {
    font-weight: var(--font-weight-bold);
    margin-right: 1rem;
    min-width: 3ch;
    font-size: var(--font-size-controls);
    color: var(--accent-success);
}

.modal-button-name {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
}

/* Danger button styles (red) */
.modal-button.danger {
    font-weight: var(--font-weight-bold);
    border: 1px solid var(--accent-error);
    color: var(--accent-error);
}

.modal-button.danger:hover,
.modal-button.danger.selected {
    background-color: var(--accent-error);
    color: var(--background-primary);
    transform: translateX(4px);
}

body.no-animations .modal-overlay,
body.no-animations .modal,
body.no-animations .modal-button {
    transition: none !important;
}

body.no-animations .modal {
    transform: none !important;
    opacity: 1 !important;
}

body.no-animations .modal-button:hover,
body.no-animations .modal-button.selected,
body.no-animations .modal-button.danger:hover,
body.no-animations .modal-button.danger.selected {
    transform: none !important;
}

.modal-button.danger .modal-button-prefix {
    color: var(--accent-error);
}

/* ESC to close hint */
.modal-esc-hint {
    text-align: center;
    margin-top: 0.75rem;
    font-size: 0.68rem;
    color: var(--text-tertiary);
    opacity: 0.6;
    user-select: none;
    pointer-events: none;
}

.modal-esc-hint kbd {
    font-family: var(--font-family-main);
    font-size: 0.65rem;
    font-weight: var(--font-weight-semibold);
    padding: 0.1rem 0.32rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-tertiary);
    border-radius: 3px;
    letter-spacing: 0.04em;
    line-height: 1;
    vertical-align: baseline;
}

.modal-esc-hint:empty {
    display: none;
}

@media (pointer: coarse) {
    .modal-esc-hint { display: none; }
}

/* Modal select styling */
.modal-select {
    width: 100%;
    padding: 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-controls);
    margin-top: 0.5rem;
}

/* Modal page list styling */
.modal-page-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.modal-page-btn {
    padding: 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: var(--font-size-controls);
    transition: background-color 0.3s ease;
}

.modal-page-btn:hover:not(.current) {
    background-color: var(--background-secondary);
}

.modal-page-btn.current {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Keyboard cheat sheet: accordion style ───────────────────────────────── */

.keyboard-cheat-sheet {
    width: 100%;
}

.cheat-sheet-filter {
    width: 100%;
    box-sizing: border-box;
    background: transparent;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.82rem;
    margin-bottom: 0.75rem;
    outline: none;
    padding: 0.35rem 0.65rem;
    transition: border-color 0.12s;
}
.cheat-sheet-filter:focus {
    border-color: var(--accent-primary);
}
.cheat-sheet-filter::placeholder {
    color: var(--text-tertiary);
    opacity: 0.65;
}

.cheat-sheet-no-results {
    margin: 0.75rem 0 0;
    color: var(--text-tertiary);
    font-size: 0.9rem;
}

/*
 * One line naming the view the sheet was opened from, above the filter. Only
 * shown outside the bookmarks default, where there is nothing to explain.
 */
.cheat-sheet-context-lead {
    margin: 0 0 0.6rem;
    font-size: 0.72rem;
    color: var(--text-secondary);
}

.cheat-sheet-group {
    border-bottom: 1px solid var(--border-primary);
}

/*
 * The section matching the current view. Marked rather than moved or isolated:
 * every other section stays in place and the filter still searches them all.
 */
.cheat-sheet-group--context > .cheat-sheet-group-title {
    border-left: 2px solid var(--accent-primary);
    padding-left: 0.5rem;
    margin-left: -0.5rem;
    color: var(--accent-primary);
}

.cheat-sheet-group:last-child {
    border-bottom: none;
}

.cheat-sheet-group-title {
    list-style: none;
    cursor: pointer;
    padding: 0.5rem 0;
    font-size: 0.7rem;
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.06em;
    text-transform: lowercase;
    color: var(--text-tertiary);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    user-select: none;
    border-radius: var(--layout-radius-xs, 6px);
}

.cheat-sheet-group-title::-webkit-details-marker {
    display: none;
}

.cheat-sheet-group-title::before {
    content: '▶';
    font-size: 0.5rem;
    color: var(--text-tertiary);
    transition: transform 0.15s ease;
    display: inline-block;
}

.cheat-sheet-group[open] .cheat-sheet-group-title::before {
    transform: rotate(90deg);
}

.cheat-sheet-group-title:hover {
    color: var(--text-secondary);
}

/* Keyboard clarity: always show where focus is inside cheat sheet modal. */
.keyboard-cheat-sheet-modal .cheat-sheet-filter:focus-visible,
.keyboard-cheat-sheet-modal .cheat-sheet-group-title:focus-visible,
.keyboard-cheat-sheet-modal .modal-button:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent-primary) 82%, #fff 18%);
    outline-offset: 2px;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 24%, transparent);
}

.keyboard-cheat-sheet-modal .cheat-sheet-group-title:focus-visible {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
}

.keyboard-cheat-sheet-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
    margin-bottom: 0.5rem;
}

.keyboard-cheat-sheet-table td {
    padding: 0.22rem 0;
    border-bottom: 1px solid var(--border-primary);
    vertical-align: top;
    line-height: 1.35;
}

.keyboard-cheat-sheet-table tr:last-child td {
    border-bottom: none;
}

.keyboard-cheat-sheet-keys {
    font-family: "Source Code Pro", monospace;
    font-size: 0.8rem;
    font-weight: var(--font-weight-bold);
    color: var(--accent-primary);
    white-space: normal;
    word-break: break-word;
    padding-right: 1rem;
    width: 40%;
}

.keyboard-cheat-sheet-description {
    color: var(--text-secondary);
    font-size: 0.875rem;
    min-width: 0;
    overflow-wrap: anywhere;
    width: 60%;
}

@media (prefers-reduced-motion: reduce) {
    /* Modal open/close → keep opacity fade, remove scale + translate */
    .modal { transform: none !important; transition: opacity 0.15s ease !important; }
    .modal-overlay.show .modal { transform: none !important; }
    .modal-button,
    .modal-button:hover,
    .modal-button.selected,
    .modal-button.danger:hover,
    .modal-button.danger.selected { transition: none !important; transform: none !important; }
    .wn-kofi-btn--animated,
    .wn-kofi-btn--animated::before,
    .wn-kofi-star {
        animation: none !important;
    }
    .wn-kofi-btn--animated {
        box-shadow: 0 0 0.5rem 0.1rem color-mix(in srgb, var(--accent-primary) 28%, transparent);
    }
    .wn-kofi-star {
        opacity: 0.75;
        transform: scale(1);
    }
}

/* ==== css/app-notification.css ==== */
/* Unified toast / notification host (#app-notification) */

.app-notification {
    position: fixed;
    right: max(1rem, env(safe-area-inset-right));
    bottom: max(1rem, env(safe-area-inset-bottom));
    max-width: min(380px, calc(100vw - 1.5rem));
    padding: 0.75rem 1rem;
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
    font-family: var(--font-family-main);
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-primary);
    border-radius: 0.35rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.14);
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    transition: opacity 0.24s ease, visibility 0.24s ease, transform 0.24s ease;
    z-index: 2001;
    pointer-events: none;
}

.app-notification.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto;
}

.app-notification.has-action {
    max-width: min(420px, calc(100vw - 1.5rem));
}

.app-notification.success {
    color: var(--accent-success);
    border-color: var(--accent-success);
}

.app-notification.error {
    color: var(--accent-error);
    border-color: var(--accent-error);
}

.app-notification.warning {
    color: var(--accent-warning);
    border-color: var(--accent-warning);
}

.app-notification.info {
    color: var(--text-secondary);
    border-color: var(--border-primary);
}

/* Software update available — accent brand colour, distinct from success/error. */
.app-notification.update {
    color: var(--accent-primary);
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-secondary));
}

/* One-time discoverability promos — themed like config setting highlights. */
.app-notification.promo {
    color: var(--text-primary);
    border-color: color-mix(in srgb, var(--accent-primary) 42%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 11%, var(--background-secondary));
    box-shadow:
        0 4px 18px color-mix(in srgb, var(--accent-primary) 16%, transparent),
        0 0 0 1px color-mix(in srgb, var(--accent-primary) 14%, transparent);
}

.app-notification.promo .app-notification-text {
    font-weight: var(--font-weight-medium);
}

.app-notification-promo-label {
    display: inline-block;
    margin-right: 0.35rem;
    padding: 0.1rem 0.42rem;
    border-radius: 999px;
    font-size: 0.72em;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.05em;
    text-transform: uppercase;
    vertical-align: baseline;
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 18%, transparent);
}

/* Session tip: a longer, quieter toast that carries inline <code> keys. */
.app-notification.info .app-notification-text {
    font-weight: var(--font-weight-medium);
}

.app-notification-tip-label {
    color: var(--accent-warning);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    font-size: 0.78em;
    letter-spacing: 0.06em;
    margin-right: 0.15rem;
}

.app-notification-text code {
    font-family: var(--font-family-main);
    font-size: 0.88em;
    background: color-mix(in srgb, var(--text-primary) 8%, transparent);
    border: 1px solid var(--border-primary);
    border-radius: 3px;
    padding: 0.03rem 0.26rem;
    color: var(--text-primary);
    white-space: nowrap;
}

.app-notification-text {
    flex: 1;
    min-width: 0;
    line-height: 1.35;
}

.app-notification-action {
    flex-shrink: 0;
    border: 1px solid currentColor;
    background: transparent;
    color: inherit;
    border-radius: 0.25rem;
    padding: 0.25rem 0.55rem;
    font-size: var(--font-size-controls);
    font-family: inherit;
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.app-notification-action:hover {
    background: color-mix(in srgb, currentColor 12%, transparent);
}

.app-notification:not(.persist) {
    position: fixed;
}

.app-notification:not(.persist)::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 2px;
    background: currentColor;
    opacity: 0.35;
    transform-origin: left center;
    transform: scaleX(0);
}

.app-notification.show:not(.persist)::after {
    animation: app-notification-timeout var(--notification-duration, 5s) linear forwards;
}

@keyframes app-notification-timeout {
    from { transform: scaleX(1); }
    to { transform: scaleX(0); }
}

@media (max-width: 575px) {
    .app-notification {
        right: max(0.75rem, env(safe-area-inset-right));
        bottom: max(0.75rem, env(safe-area-inset-bottom));
    }
}

body.no-animations .app-notification {
    transition: none !important;
    transform: none !important;
}

body.no-animations .app-notification.show:not(.persist)::after {
    animation: none !important;
}

@media (prefers-reduced-motion: reduce) {
    .app-notification { transform: none !important; transition: opacity 0.15s ease, visibility 0.15s ease !important; }
    .app-notification.show:not(.persist)::after { animation: none !important; }
}

/* ==== css/favicon-prefetch.css ==== */
/**
 * Favicon batch prefetch overlay.
 *
 * Shared by config (after an import) and the dashboard (`:favicons fetch`), so
 * it lives outside the config-only stylesheets. Colours come from the theme
 * variables only.
 */
.favicon-prefetch-overlay {
    position: fixed;
    inset: 0;
    z-index: 12000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
    backdrop-filter: blur(2px);
}

.favicon-prefetch-overlay[hidden] {
    display: none !important;
}

.favicon-prefetch-panel {
    width: min(22rem, 100%);
    padding: 1rem 1.1rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary, var(--background-primary));
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.favicon-prefetch-title {
    margin: 0;
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.favicon-prefetch-bar-track {
    height: 0.45rem;
    border-radius: 999px;
    overflow: hidden;
    background: color-mix(in srgb, var(--text-secondary) 18%, transparent);
}

.favicon-prefetch-bar-fill {
    height: 100%;
    width: 0;
    border-radius: inherit;
    background: var(--accent-primary, var(--text-primary));
    transition: width 0.2s ease;
}

.favicon-prefetch-status {
    margin: 0;
    font-size: var(--font-size-small);
    color: var(--text-secondary);
}

/* ==== css/search.css ==== */
/* Search Component Styles */

/* Shortcut Search - anchored above bottom toolbar (classic + shared) */
.shortcut-search {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    padding: 0 max(1.25rem, 2vw) calc(var(--dashboard-toolbar-stack, 5.75rem) + env(safe-area-inset-bottom, 0px));
    box-sizing: border-box;
    z-index: 2000;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease-out, visibility 0s linear 0.2s;
    background: rgba(0, 0, 0, 0.3);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

.shortcut-search.show {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.2s ease-out, visibility 0s linear 0s;
}

.search-container {
    padding: 1rem 1.25rem 0.75rem;
    width: min(52rem, calc(100vw - 2.5rem));
    max-width: 100%;
    border: 1px solid color-mix(in srgb, var(--border-primary) 75%, transparent);
    border-radius: var(--layout-radius-md, 12px);
    background: color-mix(in srgb, var(--background-modal) 90%, transparent);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
    max-height: min(70vh, calc(100vh - var(--dashboard-toolbar-stack, 5.75rem) - 2.5rem));
    overflow: hidden;
    box-sizing: border-box;
    /* exit: slide down toward toolbar */
    transform: translateY(10px) scale(0.98);
    opacity: 0;
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

.shortcut-search.show .search-container {
    transform: translateY(0) scale(1);
    opacity: 1;
    /* entrance: spring — vertraagt soepel aan het einde */
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

.search-prompt {
    display: flex;
    align-items: center;
    font-size: var(--font-size-bookmark);
    font-weight: var(--font-weight-semibold);
    margin-bottom: 0.5rem;
    justify-content: flex-start;
}

.search-prefix {
    font-family: var(--font-family-main);
    margin-right: 0.5rem;
    color: var(--accent-success);
    font-size: 0.65em;
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.06em;
    padding: 0.15em 0.45em;
    border-radius: var(--layout-radius-sm, 8px);
    background: color-mix(in srgb, var(--accent-success) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-success) 35%, transparent);
    transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
    white-space: nowrap;
    flex-shrink: 0;
}

.search-prefix[data-mode="command"] {
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 15%, transparent);
    border-color: color-mix(in srgb, var(--accent-primary) 35%, transparent);
}

.search-prefix[data-mode="finder"] {
    color: var(--accent-secondary);
    background: color-mix(in srgb, var(--accent-secondary) 15%, transparent);
    border-color: color-mix(in srgb, var(--accent-secondary) 35%, transparent);
}

.search-prefix[data-mode="fuzzy"] {
    color: var(--text-secondary);
    background: color-mix(in srgb, var(--text-secondary) 12%, transparent);
    border-color: color-mix(in srgb, var(--text-secondary) 25%, transparent);
}

.search-prefix[data-mode="search"],
.search-prefix:not([data-mode]) {
    color: var(--accent-success);
    background: color-mix(in srgb, var(--accent-success) 15%, transparent);
    border-color: color-mix(in srgb, var(--accent-success) 35%, transparent);
}

.search-query {
    font-family: var(--font-family-main);
    color: var(--text-primary);
    white-space: nowrap;
    overflow-x: auto;
    display: inline-block;
    max-width: 100%;
    scrollbar-width: none; /* Firefox */
}

.search-query::-webkit-scrollbar {
    display: none; /* Chrome, Safari, and Opera */
}

.search-cursor {
    font-family: var(--font-family-main);
    animation: blink 1s infinite;
    margin-left: 0.25rem;
    color: var(--text-primary);
}

@keyframes blink {
    0%, 50% { opacity: 1; }
    51%, 100% { opacity: 0; }
}

/* Mobile input - positioned off-screen but visible to Safari */
.search-input-mobile {
    position: absolute;
    left: -9999px;
    top: -9999px;
    width: 1px;
    height: 1px;
    border: none;
    padding: 0;
    margin: 0;
    opacity: 0.01;
}

.search-matches {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
    overflow-x: hidden;
    padding-left: 0;
    margin-left: 0;
    position: relative;
    width: 100%;
    scrollbar-width: none;
}

@media (max-width: 575px) {
    .search-container {
        width: calc(100vw - 1.5rem);
        max-height: calc(100dvh - 1.5rem);
        padding: 0.85rem 1rem 0.65rem;
        border-radius: 10px;
    }

    .search-matches {
        padding-left: 0;
        margin-left: 0;
    }
}

.search-matches::-webkit-scrollbar {
    display: none; /* Chrome, Safari, and Opera */
}

.search-matches:empty {
    min-height: 0;
}

.search-match {
    padding: 0.4rem 0.5rem;
    cursor: pointer;
    transition: background 0.1s ease, color 0.1s ease, border-color 0.1s ease;
    border: none;
    border-left: 2px solid transparent;
    border-radius: 4px;
    background: transparent;
    text-align: left;
    display: flex;
    align-items: center;
    color: var(--text-primary);
    position: relative; /* Necesario para el ::before */
    /* Remove tap highlight on mobile */
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.search-match:hover,
.search-match.keyboard-selected {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--accent-primary) 9%, transparent);
    border-left-color: var(--accent-primary);
    transform: none;
}

.search-match.keyboard-selected::before {
    content: none;
}

.search-match.command-entry.command-just-applied {
    animation: command-palette-flash 0.55s ease;
}

@keyframes command-palette-flash {
    0%, 100% {
        background: color-mix(in srgb, var(--accent-primary) 9%, transparent);
    }
    45% {
        background: color-mix(in srgb, var(--accent-success) 28%, transparent);
        border-left-color: var(--accent-success);
    }
}

.search-match-shortcut {
    font-weight: var(--font-weight-bold);
    margin-right: 1rem;
    min-width: 3ch;
    font-size: var(--font-size-controls);
    color: var(--accent-success);
}

.search-match-favicon-slot {
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-right: 0.6rem;
    border-radius: 6px;
    overflow: hidden;
}

.search-match-favicon-slot .bookmark-icon {
    width: 16px;
    height: 16px;
    display: block;
}

.search-match-name {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    min-width: 0;
}

.search-match-meta {
    display: block;
    margin-top: 0.08rem;
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-normal);
    color: var(--text-tertiary);
}

/* Command group headers */
.search-command-group-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.5rem 0.2rem;
    cursor: pointer;
    user-select: none;
    margin-top: 0.25rem;
    border-top: 1px solid color-mix(in srgb, var(--border-primary) 60%, transparent);
    opacity: 0.55;
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    transition: opacity 0.15s ease;
}

.search-command-group-header:first-child {
    border-top: none;
    margin-top: 0;
}

.search-command-group-header:hover,
.search-command-group-header.keyboard-selected {
    opacity: 1;
}

.search-command-group-header.keyboard-selected {
    color: var(--text-primary);
}

.search-command-group-header.keyboard-selected .search-command-group-label {
    color: var(--text-primary);
}

.search-command-group-arrow {
    font-size: 0.7em;
    width: 1em;
    text-align: center;
    color: var(--accent-success);
    flex-shrink: 0;
}

.search-command-group-label {
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-secondary);
    flex: 1;
}

.search-command-group-count {
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    opacity: 0.7;
}

.search-match.command-group-child {
    padding-left: 1.25rem;
}

/* Special styling for config entry */
.search-match.config-entry .search-match-shortcut {
    color: var(--accent-warning);
}

.search-match.config-entry .search-match-name {
    color: var(--accent-warning);
}

.search-match.filter-completion-entry .search-match-shortcut {
    color: var(--accent-info, var(--accent-success));
}

.search-match.filter-completion-entry .search-match-name {
    color: var(--text-secondary);
}

.search-match.whats-new-entry .search-match-shortcut {
    color: var(--accent-warning, #f59e0b);
}

.search-match.whats-new-entry .search-match-name {
    color: var(--text-primary);
}

/* Finder entries */
.search-match.finder-entry .search-match-shortcut {
    color: var(--accent-info, #60a5fa);
}

/* No-match state */
.search-match.search-no-match-header {
    opacity: 0.9;
    cursor: default;
    pointer-events: none;
    padding: 0.45rem 0.75rem;
}

.search-no-match-label {
    color: var(--text-secondary);
    margin-right: 0.3em;
}

.search-no-match-query {
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.search-match.search-no-match-header:hover,
.search-match.search-no-match-header.keyboard-selected {
    transform: none;
    color: inherit;
}

.search-match.search-hint-entry {
    opacity: 0.7;
    border-left: 2px solid transparent;
    padding-left: 0.25rem;
    transition: opacity 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.search-match.search-hint-entry:hover {
    opacity: 1;
    border-left-color: var(--accent-primary, #4287f5);
}

.search-hint-shortcut {
    color: var(--accent-primary, #4287f5);
    font-family: "Source Code Pro", monospace;
    font-size: 0.82em;
    letter-spacing: 0.02em;
}

.search-hint-name {
    font-weight: var(--font-weight-normal);
    color: var(--text-secondary);
}

.search-match-use-count {
    flex-shrink: 0;
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    font-weight: var(--font-weight-normal);
    min-width: 2ch;
    text-align: right;
    opacity: 0.7;
}

/* Button Container - Centered at bottom */
/* Fixed max width so tip text length does not change container width (avoids button row jumping). */
.button-container {
    position: fixed;
    bottom: 2rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-content: flex-start;
    gap: 0.55rem;
    z-index: 1000;
    width: min(52rem, calc(100vw - 2.5rem));
    max-width: 100%;
    box-sizing: border-box;
    padding: 0.7rem 0 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

.search-flow-hint {
    /* Absolutely positioned above the button row — not in flex flow, so
       hiding it causes zero layout shift to the buttons below. */
    position: absolute;
    bottom: calc(100% + 0.85rem);
    left: 0;
    right: 0;

    display: flex;
    justify-content: center;
    align-items: center;

    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    letter-spacing: 0.05em;
    pointer-events: none;

    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.45s ease, transform 0.45s ease;
}

.search-flow-hint[hidden] {
    display: none !important;
}

.search-flow-hint.dismissing {
    opacity: 0;
    transform: translateY(-8px);
}

.search-flow-chip,
kbd.search-flow-chip {
    display: inline-block;
    margin: 0 0.05rem;
    color: var(--accent-primary);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-semibold);
    text-shadow: 0 0 10px color-mix(in srgb, var(--accent-primary) 55%, transparent);
    border: none;
    background: transparent;
    padding: 0;
}

.search-flow-hint .sfh-seg-label {
    margin-left: 0.15em;
}

/* Each text segment wipes in left-to-right via clip-path — no extra chars, no fade */
.sfh-seg {
    display: inline-block;
    animation: sfhWipe 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Chip chars get an extra scale-bounce on top of the wipe */
.sfh-seg.search-flow-chip,
.sfh-seg kbd.search-flow-chip {
    animation: sfhWipe 0.3s cubic-bezier(0.22, 1, 0.36, 1) both,
               sfhPop  0.38s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Staggered delays: chips pause slightly longer after each separator */
.search-flow-hint-text > .sfh-seg:nth-child(1)  { animation-delay: 0.15s; }
.search-flow-hint-text > .sfh-seg:nth-child(2)  { animation-delay: 0.32s; }
.search-flow-hint-text > .sfh-seg:nth-child(3)  { animation-delay: 0.60s; }
.search-flow-hint-text > .sfh-seg:nth-child(4)  { animation-delay: 0.82s; }
.search-flow-hint-text > .sfh-seg:nth-child(5)  { animation-delay: 0.98s; }
.search-flow-hint-text > .sfh-seg:nth-child(6)  { animation-delay: 1.26s; }
.search-flow-hint-text > .sfh-seg:nth-child(7)  { animation-delay: 1.46s; }
.search-flow-hint-text > .sfh-seg:nth-child(8)  { animation-delay: 1.60s; }
.search-flow-hint-text > .sfh-seg:nth-child(9)  { animation-delay: 1.88s; }
.search-flow-hint-text > .sfh-seg:nth-child(10) { animation-delay: 2.08s; }
.search-flow-hint-text > .sfh-seg:nth-child(11) { animation-delay: 2.22s; }

@keyframes sfhWipe {
    from { clip-path: inset(0 100% 0 0); }
    to   { clip-path: inset(0 0%   0 0); }
}

@keyframes sfhPop {
    from { transform: scale(0.5); text-shadow: 0 0 24px color-mix(in srgb, var(--accent-primary) 100%, transparent); }
    65%  { transform: scale(1.3); }
    to   { transform: scale(1);   text-shadow: 0 0 10px color-mix(in srgb, var(--accent-primary) 55%, transparent); }
}

body.no-animations .search-flow-hint {
    transition: none !important;
}

body.no-animations .sfh-seg {
    animation: none !important;
    clip-path: none !important;
}

/* Custom tooltips on search buttons — appear above on hover */
.search-button[data-tooltip] {
    position: relative;
}

.search-button[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    padding: 0.2rem 0.5rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.3rem;
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.85);
    font-weight: var(--font-weight-normal);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
    z-index: 1001;
}

.search-button[data-tooltip]:hover::after {
    opacity: 1;
    visibility: visible;
}

/* No tooltips on touch — hover doesn't exist there */
@media (pointer: coarse) {
    .search-button[data-tooltip]::after {
        display: none;
    }
}

body.no-animations .search-button[data-tooltip]::after {
    transition: none !important;
}

/* Search Button */
.search-button {
    /* Button styling */
    padding: 0.62rem 0.92rem;
    border: 1px solid var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 74%, transparent);
    color: var(--text-secondary);
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    font-weight: var(--font-weight-normal);
    cursor: pointer;
    
    /* TTY terminal style */
    display: flex;
    align-items: center;
    gap: 0.5rem;
    border-radius: var(--layout-radius-md, 0.65rem);
    
    /* Transitions */
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
    
    /* Remove tap highlight on mobile */
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.search-button:hover {
    background: var(--background-secondary);
    border-color: var(--border-primary);
    color: var(--text-primary);
    transform: none;
    box-shadow: none;
}

.search-button:active {
    transform: none;
    background: var(--background-secondary);
    border-color: var(--border-primary);
    color: var(--text-primary);
    box-shadow: none;
}

.search-button:focus-visible {
    outline: 2px solid var(--border-primary);
    outline-offset: 2px;
    color: var(--text-primary);
}

.search-button-icon {
    display: inline-block; /* required for transform to work on <span> */
    color: var(--text-secondary);
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-category);
}

.search-button:hover .search-button-icon,
.search-button:focus-visible .search-button-icon {
    color: var(--text-primary);
}

/* ── Periodic attention pulse on search / commands / finders icons ───────
   Total cycle = 10.8 s: 0.8 s of motion (0 – 7.4 %), then 10 s idle.
   The three icons are staggered 3.6 s apart so they pulse one by one.   */
@keyframes btnIconPulse {
    0%   { opacity: 1; }
    4%   { opacity: 0.45; }
    8%   { opacity: 1; }
    100% { opacity: 1; }
}

#search-button .search-button-icon,
.add-bookmark-button .search-button-icon,
.commands-button .search-button-icon,
.finders-button .search-button-icon,
.recent-button .search-button-icon,
.help-button .search-button-icon {
    animation: btnIconPulse 10.8s ease-in-out infinite;
}
#search-button .search-button-icon         { animation-delay: 1s;   }
.add-bookmark-button .search-button-icon  { animation-delay: 2.8s; }
.commands-button .search-button-icon       { animation-delay: 4.6s; }
.finders-button .search-button-icon        { animation-delay: 6.4s; }
.recent-button .search-button-icon         { animation-delay: 8.2s; }
.help-button .search-button-icon           { animation-delay: 9.4s; }

body.no-animations #search-button .search-button-icon,
body.no-animations .add-bookmark-button .search-button-icon,
body.no-animations .commands-button .search-button-icon,
body.no-animations .finders-button .search-button-icon,
body.no-animations .recent-button .search-button-icon,
body.no-animations .help-button .search-button-icon {
    animation: none !important;
}

/* Hide buttons when search is active */
.shortcut-search.show ~ .button-container {
    opacity: 0;
    pointer-events: none;
}

/* Preserve transforms when animations are disabled */
body.no-animations .search-button {
    transform: none !important;
}

/* Disable hover transforms when animations are disabled */
body.no-animations .search-button:hover {
    transform: none !important;
}

body.no-animations .search-button:active {
    transform: none !important;
}

/* Disable search match hover transforms when animations are disabled */
body.no-animations .search-match:hover,
body.no-animations .search-match.keyboard-selected {
    transform: none !important;
}

/* ─── Btn-group wrappers ──────────────────────────────────────────────────── */
/* In bottom-modus: transparant voor de bestaande flex-layout van .button-container */
.btn-group {
    display: contents;
}


/* ─── Side-dock: gedeeld (left + right) ──────────────────────────────────── */
body[data-button-position="bottom-left"] .button-container,
body[data-button-position="bottom-right"] .button-container {
    flex-direction: row;
    align-items: flex-end;
    width: auto;
    padding: 0;
    gap: 0.35rem;
    border-radius: 0;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    box-shadow: none;
    left: unset;
    transform: none;
    bottom: 1.5rem;
}

body[data-button-position="bottom-left"] .btn-group,
body[data-button-position="bottom-right"] .btn-group {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

body[data-button-position="bottom-left"] .btn-group-secondary,
body[data-button-position="bottom-right"] .btn-group-secondary {
    padding-top: 0;
    border-top: none;
}



/* search-flow-hint past niet in de dock */
body[data-button-position="bottom-left"] .search-flow-hint,
body[data-button-position="bottom-right"] .search-flow-hint {
    display: none !important;
}

/* ─── Rechter-dock ───────────────────────────────────────────────────────── */
body[data-button-position="bottom-right"] .button-container {
    right: 1rem;
}
body[data-button-position="bottom-right"] .btn-group-secondary { order: 0; }
body[data-button-position="bottom-right"] .btn-group-primary   { order: 1; }

/* ─── Linker-dock ────────────────────────────────────────────────────────── */
body[data-button-position="bottom-left"] .button-container {
    left: 1rem;
}
body[data-button-position="bottom-left"] .btn-group-primary   { order: 0; }
body[data-button-position="bottom-left"] .btn-group-secondary { order: 1; }

/* ─── Tooltips richting omdraaien in side-dock ───────────────────────────── */
body[data-button-position="bottom-left"] .search-button[data-tooltip]::after {
    bottom: auto;
    top: 50%;
    left: calc(100% + 8px);
    transform: translateY(-50%);
}
body[data-button-position="bottom-right"] .search-button[data-tooltip]::after {
    bottom: auto;
    top: 50%;
    right: calc(100% + 8px);
    left: auto;
    transform: translateY(-50%);
}


/* ─── Hover-richting: weg van de rand ────────────────────────────────────── */
body[data-button-position="bottom-right"] .search-button:hover {
    transform: translateX(-2px);
}
body[data-button-position="bottom-left"] .search-button:hover {
    transform: translateX(2px);
}
body[data-button-position="bottom-right"] .search-button:active,
body[data-button-position="bottom-left"] .search-button:active {
    transform: translateX(0);
}

/* Ensure button container remains centered when animations are disabled */
body.no-animations .button-container {
    transform: translateX(-50%) !important;
}
/* Side rail: no-animations must not re-center the rail */
body.no-animations[data-button-position="side-left"] .button-container {
    transform: none !important;
}

body.no-animations .shortcut-search,
body.no-animations .search-container {
    transition: none !important;
}

/* Fuzzy search highlight */
.fuzzy-highlight {
    font-weight: var(--font-weight-bold);
    text-transform: uppercase;
}

/* Query match highlight in search results */
mark.search-highlight {
    background: transparent;
    color: inherit;
    font-weight: var(--font-weight-bold);
    text-decoration: underline;
    text-decoration-color: var(--text-secondary);
    text-underline-offset: 2px;
}

/* Search mode tabs — shown at the bottom of the search container */
.search-mode-tabs {
    display: flex;
    gap: 0.4rem;
    padding-top: 0.6rem;
    margin-top: 0.4rem;
    border-top: 1px solid color-mix(in srgb, var(--border-primary) 60%, transparent);
    flex-shrink: 0;
}

.search-mode-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    border: 1px solid color-mix(in srgb, var(--border-primary) 70%, transparent);
    border-radius: 999px;
    background: transparent;
    color: var(--text-tertiary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.9);
    cursor: pointer;
    transition: background 0.13s ease, border-color 0.13s ease, color 0.13s ease;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    white-space: nowrap;
}

.search-mode-tab:hover {
    color: var(--text-secondary);
    border-color: var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 60%, transparent);
}

.search-mode-tab:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-radius: 999px;
}

.search-mode-tab-key {
    font-weight: var(--font-weight-bold);
    font-size: 1em;
    line-height: 1;
}

/* Active states — match the search-prefix badge colours */
.search-mode-tab.active[data-mode="search"] {
    color: var(--accent-success);
    background: color-mix(in srgb, var(--accent-success) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent-success) 35%, transparent);
}

.search-mode-tab.active[data-mode="command"] {
    color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent-primary) 35%, transparent);
}

.search-mode-tab.active[data-mode="finder"] {
    color: var(--accent-secondary);
    background: color-mix(in srgb, var(--accent-secondary) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent-secondary) 35%, transparent);
}

/* Hide on mobile extra-small to save vertical space */
@media (max-width: 479px) {
    .search-mode-tabs {
        display: none;
    }
}

body.no-animations .search-mode-tab {
    transition: none !important;
}

/* ─── Recent search chips ────────────────────────────────────── */
.search-history-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    padding: 0.4rem 1.25rem 0.5rem;
}

.search-history-chip-wrap {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    max-width: 100%;
}

.search-history-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    border: 1px solid var(--border-primary);
    background: transparent;
    color: var(--text-secondary);
    font-size: 0.72rem;
    font-family: inherit;
    line-height: 1.4;
    cursor: pointer;
    white-space: nowrap;
    max-width: 18ch;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

.search-history-chip:hover {
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
    border-color: var(--text-secondary);
    color: var(--text-primary);
}

.search-history-chip:focus-visible,
.search-history-chip.keyboard-selected-chip {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-radius: 999px;
}

.search-history-chip.keyboard-selected-chip {
    background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

.search-history-chip-row.keyboard-selected {
    background: color-mix(in srgb, var(--accent-primary) 6%, transparent);
    border-radius: 0.35rem;
}

.search-history-chip-remove,
.search-history-remove {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--text-tertiary);
    font-size: 0.95rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.12s ease, color 0.12s ease, background 0.12s ease;
}

.search-history-chip-wrap:hover .search-history-chip-remove,
.search-match.history-entry:hover .search-history-remove,
.search-history-chip-remove:focus-visible,
.search-history-remove:focus-visible {
    opacity: 1;
    outline: 2px solid var(--accent-primary);
    outline-offset: 1px;
    border-radius: 999px;
}

.search-history-chip-remove:hover,
.search-history-remove:hover {
    color: var(--accent-error);
    background: color-mix(in srgb, var(--accent-error) 12%, transparent);
}

.search-match.history-entry {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.search-match.history-entry .search-match-name {
    flex: 1 1 auto;
    min-width: 0;
}

body.no-animations .search-history-chip,
body.no-animations .search-history-chip-remove,
body.no-animations .search-history-remove {
    transition: none !important;
}

/* Side rail / corner docks: keep centered placement */
body[data-button-position="side-left"] .shortcut-search,
body[data-button-position="bottom-left"] .shortcut-search,
body[data-button-position="bottom-right"] .shortcut-search {
    justify-content: center;
    padding-bottom: max(2rem, env(safe-area-inset-bottom, 0px));
}

body[data-button-position="side-left"] .shortcut-search .search-container,
body[data-button-position="bottom-left"] .shortcut-search .search-container,
body[data-button-position="bottom-right"] .shortcut-search .search-container {
    max-height: calc(100vh - 2rem);
}

.search-command-chip {
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 0.68rem;
    color: var(--accent-primary);
    border-color: color-mix(in srgb, var(--accent-primary) 35%, transparent);
}

.search-command-chip:hover {
    color: var(--accent-primary);
    border-color: var(--accent-primary);
}

@media (prefers-reduced-motion: reduce) {
    /* Spring entrance → opacity-only fade; remove scale/translate */
    .search-container {
        transform: none !important;
        transition: opacity 0.15s ease !important;
    }
    .shortcut-search.show .search-container {
        transition: opacity 0.2s ease !important;
    }
    /* Decorative blink cursor */
    .search-cursor { animation: none !important; opacity: 1 !important; }
    /* Staggered hint segments */
    .sfh-seg { animation: none !important; opacity: 1 !important; clip-path: none !important; }
    .search-flow-hint { transition: opacity 0.15s ease !important; }
}

/* The key that starts the mode, in front of the mode it starts. The tabs under
   the line name all four; this puts the convention where the typing happens, so
   "> to search" is legible without reading the legend — and so the way past a
   single-letter bookmark shortcut is visible when you need it. */
.search-chevron {
    font-family: var(--font-family-main);
    margin-right: 0.3rem;
    font-size: 0.85em;
    font-weight: var(--font-weight-semibold);
    color: var(--accent-success);
    opacity: 0.85;
}

.search-chevron[data-mode="command"] { color: var(--accent-primary); }
.search-chevron[data-mode="finder"] { color: var(--accent-warning); }
.search-chevron[data-mode="global"],
.search-chevron[data-mode="fuzzy"] { color: var(--text-secondary); }

/* Shown only once there is something to clear. Escape does the same, but a line
   you typed into needs an exit you can point at — and touch has no Escape. */
.search-clear {
    margin-left: 0.5rem;
    padding: 0 0.35em;
    border: 1px solid var(--border-secondary);
    border-radius: var(--layout-radius-sm, 8px);
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 0.6em;
    line-height: 1.6;
    cursor: pointer;
}

.search-clear:hover,
.search-clear:focus-visible {
    color: var(--accent-error);
    border-color: color-mix(in srgb, var(--accent-error) 45%, transparent);
}

.search-clear[hidden] {
    display: none;
}

/* ==== css/bookmark-form-modal.css ==== */
/* Shared bookmark add/edit form — modal shell around the inline editor form. */

.bookmark-form-modal {
    display: none;
    align-items: center;
    justify-content: center;
    /* Breathing room on a tall window, less of it on a short one, where those
       pixels are the difference between the form fitting and scrolling. */
    padding: clamp(8px, 3vh, 24px) 16px;
    overflow-y: auto;
    z-index: 10050;
}

.bookmark-form-modal.show {
    display: flex;
}

/*
 * The cap is what the overlay actually leaves, not a flat 90vh.
 *
 * The overlay already holds 24px of padding top and bottom, so a 90vh dialog
 * asked for 90% of the height inside a box that had 48px taken off it — the
 * form fits in 735px, and on an 800px-tall window the cap came out at 720 and
 * put a scrollbar on a form with 15px to spare. Common laptop heights (800,
 * 810) landed just under the line, so the modal scrolled for no visible reason
 * while the same form sat still on a taller screen.
 *
 * 100dvh minus that padding lets the dialog use the room the overlay is really
 * offering, and dvh rather than vh so a mobile browser's collapsing toolbar
 * does not reintroduce the same few missing pixels. The subtraction mirrors the
 * overlay's clamped padding above — the two have to agree, or the cap starts
 * describing space the overlay is not giving.
 */
.bookmark-form-modal-dialog {
    width: min(520px, 100%);
    max-height: min(calc(100dvh - (2 * clamp(8px, 3vh, 24px))), 920px);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    margin: auto;
    flex-shrink: 0;
    border-radius: 14px;
    border: 1px solid var(--border-color, rgba(128, 128, 128, 0.28));
    background: var(--background-primary, #fff);
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
}

.bookmark-form-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px 10px;
    border-bottom: 1px solid var(--border-primary, rgba(128, 128, 128, 0.15));
}

.bookmark-form-modal-header h2 {
    margin: 0;
    font-size: calc(var(--font-size-text) * 1.12);
    font-weight: 600;
}

.bookmark-form-modal-close {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: inherit;
    font-size: 1.35rem;
    line-height: 1;
    cursor: pointer;
}

.bookmark-form-modal-close:hover {
    background: var(--background-secondary, rgba(128, 128, 128, 0.12));
}

.bookmark-form-modal-body {
    overflow-y: auto;
    padding: 14px 16px 18px;
}

.bookmark-form-modal-body .bookmark-inline-form {
    max-width: none;
    margin: 0;
    padding: 0;
    border: none;
    background: transparent;
    box-shadow: none;
}

body.bookmark-form-modal-open .bookmark-inline-form,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-input,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-select,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-textarea,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-action-btn,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-create-btn,
body.bookmark-form-modal-open .bookmark-inline-form .bookmark-inline-icon-preview {
    background: var(--inline-edit-field-bg, var(--background-secondary));
}

/* Delete/discard confirms and other #app-modal prompts opened from the form. */
body.bookmark-form-modal-open #app-modal.modal-overlay.show {
    z-index: 10100;
}

/* Tag autocomplete dropdown (appended to body) must sit above the form modal. */
body.bookmark-form-modal-open .tag-ac-dropdown {
    z-index: 10150;
}

@media (max-width: 520px) {
    .bookmark-form-modal {
        padding: 12px 8px;
        align-items: center;
    }

    .bookmark-form-modal-dialog {
        max-height: none;
        min-height: min(90vh, 100%);
    }
}

/* ==== css/search-commands-new.css ==== */
/* New Bookmark Modal Styles */

/* The 520px cap used to cut the form off mid-way, so the fields between Tags
   and "More options" — availability checking among them — sat below the fold
   and had to be scrolled to before they could be seen at all. 760px shows the
   whole form down to the collapsed section on a normal window, while 90vh still
   keeps it inside a short one. The body scrolls either way. */
.modal-new-bookmark {
    max-width: 560px;
    width: min(560px, 92vw);
    padding: 0;
    overflow: hidden;
    max-height: min(90vh, 760px);
    display: flex;
    flex-direction: column;
}

.modal-new-bookmark.nbm-mobile-wizard {
    max-height: 90vh;
}

/* ── Header ── */
.nbm-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border-primary);
    background: var(--background-secondary);
    flex-shrink: 0;
}

.nbm-title {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.nbm-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* ── Form ── */
.new-bookmark-form {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.nbm-section {
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border-primary);
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.nbm-section-row {
    flex-direction: row;
    align-items: flex-end;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.nbm-section-toggles {
    flex-direction: row;
    gap: 1.25rem;
    align-items: center;
    flex-wrap: wrap;
}

/* Availability check and Shortcut share one row: the mode pills leave a column
   free beside them that the short input fits into exactly, which is what lets
   Shortcut sit above the fold without making the modal taller.
   Placed here beside .nbm-section-row rather than further down the file because
   it overrides .nbm-section's column direction at equal specificity — later
   rules win, so distance from that rule is what makes this work. */
.nbm-availability-row {
    flex-direction: row;
    align-items: flex-start;
    gap: 1rem;
}

.nbm-availability-main {
    flex: 1 1 auto;
    min-width: 0;
}

.nbm-availability-aside {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.nbm-availability-aside .nbm-input {
    width: 5.5rem;
}

/* Under the narrow breakpoint the two stack rather than squeezing the pills. */
@media (max-width: 520px) {
    .nbm-availability-row {
        flex-direction: column;
        gap: 0.6rem;
    }

    .nbm-availability-aside {
        width: 100%;
    }
}

/* ── Labels ── */
.nbm-label {
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    font-weight: var(--font-weight-semibold);
    display: block;
}

.nbm-label-hint {
    font-weight: var(--font-weight-normal, 400);
    color: var(--text-tertiary);
    font-size: calc(var(--font-size-controls) * 0.9);
    margin-left: 0.3em;
}

/* ── Inputs ── */
.nbm-input {
    width: 100%;
    padding: 0.38rem 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-text);
    transition: border-color 0.15s ease;
    box-sizing: border-box;
}

.nbm-input:focus {
    outline: none;
    border-color: var(--text-secondary);
}

.nbm-input::placeholder {
    color: var(--text-secondary);
    opacity: 0.5;
}

.nbm-note {
    resize: vertical;
    min-height: 3.5rem;
    line-height: 1.5;
    font-family: inherit;
}

.nbm-shortcut {
    text-transform: uppercase;
    text-align: center;
    max-width: 5.5rem;
}

.nbm-conflict-hint {
    display: inline;
    font-size: 0.72rem;
    color: var(--accent-error);
    white-space: nowrap;
    flex-shrink: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.nbm-conflict-hint[hidden] {
    display: none !important;
}

.nbm-shortcut.field-conflict {
    border-color: var(--accent-error);
}

.nbm-input.field-conflict {
    border-color: var(--accent-error);
}

.nbm-url-conflict-hint {
    display: block;
    margin-top: 0.35rem;
}

/* Not a conflict: the same link on another page is allowed, and this only says
   where it is. Muted rather than red for exactly that reason. */
.nbm-elsewhere-hint {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.72rem;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
}

.nbm-elsewhere-hint[hidden] {
    display: none !important;
}

.nbm-file-label {
    cursor: pointer;
}

.nbm-file-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* ── Row columns ── */
.nbm-col {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    flex: 1;
    min-width: 0;
}

.nbm-col-narrow {
    flex: 0 0 auto;
    min-width: 0;
}

/* Inline "create new page/category" row inside the add-bookmark modal. */
.nbm-new-option {
    font-style: italic;
}

.nbm-inline-create {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-top: 0.4rem;
    padding: 0.5rem;
    border: 1px dashed var(--accent-success, #34d399);
    border-radius: 8px;
    background: color-mix(in srgb, var(--accent-success, #34d399) 8%, transparent);
}

/* The [hidden] attribute must win over the display above. */
.nbm-inline-create[hidden] {
    display: none;
}

.nbm-inline-create-hint {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-secondary, #9ca3af);
    letter-spacing: 0.02em;
}

.nbm-inline-create-row {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.nbm-inline-create-row .nbm-input {
    flex: 1 1 auto;
    min-width: 0;
}

.nbm-inline-create-ok,
.nbm-inline-create-cancel {
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 8px;
    border: 1px solid transparent;
    cursor: pointer;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: filter 0.15s ease, background 0.15s ease;
}

.nbm-inline-create-ok {
    background: var(--accent-success, #34d399);
    color: #06281d;
}

.nbm-inline-create-cancel {
    background: var(--background-secondary, rgba(128, 128, 128, 0.12));
    color: var(--text-secondary, #9ca3af);
    border-color: var(--border-primary, rgba(128, 128, 128, 0.3));
}

.nbm-inline-create-ok:hover {
    filter: brightness(1.08);
}

.nbm-inline-create-cancel:hover {
    color: var(--accent-error, #fb7185);
    border-color: var(--accent-error, #fb7185);
}

/* ── More options ── */
.nbm-more-options {
    border-bottom: 1px solid var(--border-primary);
}

.nbm-more-options > summary {
    padding: 0.55rem 1rem;
    cursor: pointer;
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    list-style: none;
    user-select: none;
}

.nbm-more-options > summary::-webkit-details-marker {
    display: none;
}

.nbm-more-options > summary::before {
    content: '▸ ';
    display: inline-block;
    transition: transform 0.15s ease;
}

.nbm-more-options[open] > summary::before {
    transform: rotate(90deg);
}

.nbm-more-content {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--border-primary);
}

.nbm-more-content .nbm-section {
    border-bottom: none;
}

.nbm-more-content .nbm-section + .nbm-section {
    border-top: 1px solid var(--border-primary);
}

.nbm-more-content .bookmark-form-preview-section {
    padding: 0.65rem 1rem;
    gap: 0.65rem;
}

/* ── Mobile wizard ── */
.nbm-wizard-nav {
    display: none;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    border-bottom: 1px solid var(--border-primary);
    background: var(--background-secondary);
    flex-shrink: 0;
}

.nbm-mobile-wizard .nbm-wizard-nav {
    display: flex;
}

.nbm-wizard-step {
    flex: 1;
    text-align: center;
    font-size: 0.72rem;
    font-weight: var(--font-weight-semibold);
    color: var(--text-tertiary);
    padding: 0.25rem 0.35rem;
    border: 1px solid transparent;
}

.nbm-wizard-step.is-active {
    color: var(--text-primary);
    border-color: var(--border-primary);
    background: var(--background-primary);
}

.nbm-wizard-step.is-done {
    color: var(--text-secondary);
}

.nbm-mobile-wizard.nbm-wizard-step-2 .nbm-wizard-step-1-panel {
    display: none;
}

.nbm-mobile-wizard .nbm-section.nbm-wizard-step-2-panel {
    display: none;
}

.nbm-mobile-wizard.nbm-wizard-step-2 .nbm-section.nbm-wizard-step-2-panel {
    display: flex;
}

.nbm-mobile-wizard .nbm-more-options {
    display: none;
}

.nbm-mobile-wizard.nbm-wizard-step-2 .nbm-more-options {
    display: block;
}

.nbm-wizard-only {
    display: none;
}

.nbm-mobile-wizard .nbm-wizard-only {
    display: inline-flex;
}

.nbm-mobile-wizard.nbm-wizard-step-1 #new-bookmark-create {
    display: none;
}

.nbm-mobile-wizard.nbm-wizard-step-1 #new-bookmark-wizard-back {
    display: none;
}

.nbm-mobile-wizard.nbm-wizard-step-2 #new-bookmark-wizard-next {
    display: none;
}

.nbm-mobile-wizard:not(.nbm-wizard-step-1):not(.nbm-wizard-step-2) #new-bookmark-wizard-back,
.nbm-mobile-wizard:not(.nbm-wizard-step-1):not(.nbm-wizard-step-2) #new-bookmark-wizard-next {
    display: none;
}

/* ── URL row ── */
.nbm-url-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.nbm-url-row .nbm-input {
    flex: 1;
    min-width: 0;
}

/* ── Icon row ── */
.nbm-icon-row {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.nbm-icon-preview {
    width: 2rem;
    height: 2rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
    color: var(--text-tertiary);
}

.nbm-icon-preview img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.nbm-icon-preview-empty {
    font-size: 0.7rem;
    line-height: 1;
}

.nbm-icon-row .nbm-input {
    flex: 1;
    min-width: 0;
}

.nbm-icon-clear {
    flex-shrink: 0;
    min-width: 2rem;
    padding: 0 0.45rem;
}

.nbm-icon-state {
    font-size: var(--font-size-controls);
    color: var(--text-tertiary);
    min-height: 1em;
    padding-top: 0.1rem;
}

/* ── Toggles ── */
.nbm-toggle-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    user-select: none;
}

.nbm-toggle-label input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    border: 1px solid var(--border-primary);
    border-radius: 0;
    cursor: pointer;
    position: relative;
    margin: 0;
    flex-shrink: 0;
    background: var(--background-primary);
}

.nbm-toggle-label input[type="checkbox"]:checked {
    border-color: var(--accent-success);
}

.nbm-toggle-label input[type="checkbox"]:checked::before {
    content: 'X';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: var(--font-size-checkbox);
    font-weight: var(--font-weight-black);
    line-height: 1;
    color: var(--accent-success);
}

/* ── Buttons ── */
.nbm-btn {
    padding: 0.38rem 0.75rem;
    border: 1px solid var(--border-primary);
    background: transparent;
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
    white-space: nowrap;
    flex-shrink: 0;
}

.nbm-btn:hover {
    background: var(--background-secondary);
}

.nbm-btn-primary {
    border-color: var(--text-secondary);
    color: var(--text-primary);
}

.nbm-btn-primary:hover {
    background: var(--background-secondary);
}

.nbm-btn-secondary {
    color: var(--text-secondary);
}

/* "Create + New" — a distinct accent so it reads apart from the neutral primary
   Create button: it saves and immediately reopens the form for another. */
.nbm-btn-create-another {
    border-color: var(--accent-success, #34d399);
    color: var(--accent-success, #34d399);
}

.nbm-btn-create-another:hover {
    background: color-mix(in srgb, var(--accent-success, #34d399) 12%, transparent);
    color: var(--accent-success, #34d399);
}

/* ── Footer ── */
.nbm-footer {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    padding: 0.65rem 1rem;
    background: var(--background-secondary);
    flex-shrink: 0;
}

/* ── Responsive ── */
@media (max-width: 580px) {
    .modal-new-bookmark {
        width: min(560px, 96vw);
    }

    .nbm-section-row {
        flex-direction: column;
        gap: 0.5rem;
    }

    .nbm-col-narrow {
        flex: 1;
    }
}

/* ==== css/bookmark-form-preview.css ==== */
/* Shared bookmark form preview (dashboard tile + link preview card) */

.bookmark-form-preview-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.bookmark-form-preview-block {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.bookmark-form-preview-block-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.bookmark-form-preview-label {
    font-size: var(--font-size-controls, 0.8125rem);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-secondary);
}

.bookmark-form-preview-hint {
    font-size: 0.72rem;
    color: var(--text-tertiary);
    font-weight: var(--font-weight-normal, 400);
}

.bookmark-form-preview-empty {
    font-size: var(--font-size-controls, 0.8125rem);
    color: var(--text-tertiary);
    margin: 0;
    line-height: 1.45;
}

.bookmark-detail-link-preview-actions {
    display: flex;
    gap: 0.35rem;
    flex-shrink: 0;
}

.config-bookmark-preview-hover-zone {
    position: relative;
    max-width: 100%;
    outline: none;
}

.config-bookmark-preview {
    border: 1px solid var(--border-primary);
    border-radius: 6px;
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
    padding: 0.35rem 0.5rem;
}

.config-bookmark-preview--compact {
    max-width: 100%;
    cursor: default;
}

.config-bookmark-preview-popover {
    display: none;
    position: absolute;
    left: 0;
    top: calc(100% + 0.35rem);
    z-index: 40;
    min-width: min(22rem, 100%);
    max-width: min(28rem, calc(100vw - 2rem));
    padding: 0.5rem 0.65rem;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 35%, var(--border-primary));
    border-radius: 8px;
    background: var(--background-primary);
    box-shadow: 0 10px 28px color-mix(in srgb, var(--background-primary) 20%, transparent),
        0 0 0 1px color-mix(in srgb, var(--accent-primary) 12%, transparent);
    pointer-events: none;
}

.config-bookmark-preview-hover-zone:hover .config-bookmark-preview-popover,
.config-bookmark-preview-hover-zone:focus-within .config-bookmark-preview-popover {
    display: block;
}

.config-bookmark-preview-hover-zone:hover .config-bookmark-preview--compact,
.config-bookmark-preview-hover-zone:focus-within .config-bookmark-preview--compact {
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-primary));
}

.config-bookmark-preview-tile.bookmark-link {
    display: grid;
    grid-template-columns: minmax(1rem, max-content) minmax(0, 1fr) max-content;
    align-items: center;
    column-gap: 0.35rem;
    padding: 0.1rem 0;
    min-height: 1.55rem;
    font-size: var(--font-size-bookmark, 0.8125rem);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-primary);
    white-space: nowrap;
    max-width: 100%;
}

.config-bookmark-preview-tile .bookmark-lead {
    grid-column: 1;
    grid-row: 1;
    display: inline-flex;
    align-items: center;
    min-width: 1.1em;
    cursor: default;
}

.config-bookmark-preview-tile .bookmark-open {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    overflow: hidden;
}

.config-bookmark-preview-tile .bookmark-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.config-bookmark-preview-tile--expanded .bookmark-text {
    overflow: visible;
    text-overflow: unset;
    white-space: normal;
    word-break: break-word;
}

.config-bookmark-preview-tile--expanded.bookmark-link {
    white-space: normal;
    min-height: 2rem;
    padding: 0.15rem 0;
}

.config-bookmark-preview-tile--expanded .bookmark-open {
    flex-wrap: wrap;
    overflow: visible;
}

.config-link-preview-card {
    display: grid;
    grid-template-columns: 5.5rem 1fr;
    gap: 0.65rem;
    align-items: start;
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    padding: 0.55rem 0.65rem;
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
    margin-top: 0.25rem;
}

.config-link-preview-card-image-wrap {
    width: 5.5rem;
    height: 3.25rem;
    border-radius: 4px;
    overflow: hidden;
    background: var(--background-secondary);
    border: 1px solid var(--border-secondary);
}

.config-link-preview-card-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.config-link-preview-card-body {
    min-width: 0;
}

.config-link-preview-card-title {
    font-weight: var(--font-weight-semibold, 600);
    font-size: var(--font-size-text);
    color: var(--text-primary);
    line-height: 1.35;
    margin-bottom: 0.2rem;
}

.config-link-preview-card-desc {
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.config-link-preview-card-domain {
    margin-top: 0.35rem;
    font-size: 0.75rem;
    color: var(--text-tertiary);
}

.config-link-preview-card:not(:has(.config-link-preview-card-image-wrap)) {
    grid-template-columns: 1fr;
}

.config-bookmark-preview-tile .bookmark-shortcut {
    grid-column: 3;
    grid-row: 1;
    font-size: 0.85em;
    opacity: 0.85;
    text-align: right;
}

.config-bookmark-preview-tile .bookmark-icon-slot {
    width: 1.1em;
    height: 1.1em;
}

.config-bookmark-preview-tile .bookmark-icon-slot--empty {
    border: 1px dashed var(--border-secondary);
    border-radius: 3px;
    opacity: 0.45;
}

.config-bookmark-preview-tile .bookmark-icon {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.config-bookmark-preview-tile .status-text {
    flex-shrink: 0;
    font-size: 0.75em;
    font-weight: var(--font-weight-normal, 400);
}

.config-bookmark-preview-tile .bookmark-superscript-badge {
    flex-shrink: 0;
    width: 0.85em;
    height: 0.85em;
}

.config-bookmark-preview-tile .bookmark-superscript-badge svg {
    width: 100%;
    height: 100%;
    fill: currentColor;
}

.modal-new-bookmark .bookmark-form-preview-section {
    margin: 0.25rem 0 0.5rem;
}

.modal-new-bookmark .config-link-preview-card {
    grid-template-columns: 4.5rem 1fr;
}

.modal-new-bookmark .config-link-preview-card-image-wrap {
    width: 4.5rem;
    height: 2.75rem;
}

/* Compact preview strip (primary add-bookmark view) */
.bookmark-form-preview-strip {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.55rem;
    border: 1px solid var(--border-primary);
    border-radius: 6px;
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
    min-height: 2.35rem;
}

.bookmark-form-preview-strip-icon {
    width: 1.35rem;
    height: 1.35rem;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.bookmark-form-preview-strip-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.bookmark-form-preview-strip-icon-empty {
    display: block;
    width: 100%;
    height: 100%;
    border: 1px dashed var(--border-secondary);
    border-radius: 3px;
    opacity: 0.45;
}

.bookmark-form-preview-strip-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}

.bookmark-form-preview-strip-title {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bookmark-form-preview-strip-domain {
    font-size: 0.72rem;
    color: var(--text-tertiary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bookmark-form-preview-strip-tile {
    flex-shrink: 0;
    max-width: 42%;
    min-width: 0;
    overflow: hidden;
}

.bookmark-form-preview-strip-tile .config-bookmark-preview-tile.bookmark-link {
    font-size: 0.72rem;
    min-height: 1.35rem;
    padding: 0;
}

.nbm-section-compact-preview {
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
}

.ext-preview-section .config-link-preview-card {
    grid-template-columns: 3.5rem 1fr;
    padding: 0.45rem 0.5rem;
}

.ext-preview-section .config-link-preview-card-image-wrap {
    width: 3.5rem;
    height: 2.25rem;
}

.ext-preview-section .bookmark-form-preview-block-header {
    margin-top: 0.35rem;
}

/* The feed behind this bookmark, when Fresh knows of one.
   A quiet line under the preview: it answers "why does this one never say
   anything", which is a question asked once, not a fact to read every time. */
.bookmark-form-feed-line {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    margin: 0.5rem 0 0;
    font-size: 0.8rem;
    color: var(--text-secondary, #666);
    overflow: hidden;
}

.bookmark-form-feed-label {
    flex: 0 0 auto;
    color: var(--text-tertiary, #888);
}

.bookmark-form-feed-url {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.75rem;
}

/* ==== css/check-mode-control.css ==== */
/* ─── Availability check mode (shared) ───────────────────────────────────────
   The three-way Off / Periodic / Monitor control, used by both surfaces that
   offer the choice: the config bookmark panel and the dashboard's add-bookmark
   modal. It lives in its own file rather than in config-bookmarks-splitview.css
   because the dashboard does not load that stylesheet — copying the rules there
   is how the two would end up looking different.

   The .bookmark-detail-* names are kept even outside the config panel: the
   markup is identical on both surfaces on purpose, so one set of rules can
   style them both.
   ------------------------------------------------------------------------- */

/* Needed by the block below, and small enough to travel with it rather than
   pull the whole config panel stylesheet onto the dashboard. */
.bookmark-detail-label {
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    font-weight: var(--font-weight-semibold);
    display: block;
}

.bookmark-detail-field-hint {
    display: block;
    font-size: var(--font-size-small, 0.75rem);
    color: var(--text-tertiary);
    margin-top: 0.2rem;
}

.bookmark-detail-checkmode-header {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.bookmark-detail-checkmode-options {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    margin-top: 0.3rem;
}

.bookmark-detail-checkmode-input {
    position: absolute;
    width: 1px !important;
    height: 1px !important;
    margin: -1px !important;
    padding: 0 !important;
    border: 0 !important;
    opacity: 0 !important;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    pointer-events: none;
    appearance: none;
    -webkit-appearance: none;
}

.bookmark-detail-checkmode-option {
    padding: 0.25rem 0.6rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    background: var(--background-primary);
    color: var(--text-secondary);
    font-size: var(--font-size-controls);
    line-height: 1.2;
    cursor: pointer;
    user-select: none;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.bookmark-detail-checkmode-option:hover {
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-secondary));
    color: var(--text-primary);
}

.bookmark-detail-checkmode-input:checked + .bookmark-detail-checkmode-option {
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 14%, var(--background-primary));
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.bookmark-detail-checkmode-input:focus-visible + .bookmark-detail-checkmode-option {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.bookmark-detail-checkmode-info {
    width: 1.15rem;
    height: 1.15rem;
    padding: 0;
    border: 1px solid var(--border-secondary);
    border-radius: 50%;
    background: transparent;
    color: var(--text-tertiary);
    font-size: 0.7rem;
    font-style: italic;
    line-height: 1;
    cursor: pointer;
    flex: 0 0 auto;
}

.bookmark-detail-checkmode-info:hover {
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

.bookmark-detail-checkmode .bookmark-detail-field-hint {
    margin-top: 0.35rem;
}

.bookmark-detail-checkmode .custom-select-wrapper,
.bookmark-detail-checkmode .bookmark-detail-toggle-select {
    flex: 0 1 auto;
    width: auto;
    min-width: 0;
}

@media (prefers-reduced-motion: reduce) {
    .bookmark-detail-checkmode-option {
        transition: none;
    }
}

/* The modal is narrower than the config panel, so the row wraps rather than
   pushing the interval select off the edge. */
.modal-new-bookmark .bookmark-detail-checkmode-options {
    row-gap: 0.35rem;
}

/* ─── Explainer stacking ─────────────────────────────────────────────────────
   The (i) explainer is opened from surfaces that are themselves modals — the
   add-bookmark modal, the inline editor — and every overlay in the app sits at
   z-index 2000. A tie is broken by DOM order, and #app-modal is created first,
   so without this the explanation opens *behind* the form that asked for it.
   ------------------------------------------------------------------------- */
#app-modal.modal-overlay:has(.check-mode-explain-modal) {
    z-index: 2100;
}


/* ─── Icon toggle (shared) ───────────────────────────────────────────────────
   The compact checkbox-as-pill used for Pinned. Moved out of config-lists.css
   so the dashboard's add-bookmark modal can use the same control — that page
   does not load the config stylesheets, and a second copy is how the two would
   drift apart.
   ------------------------------------------------------------------------- */
.icon-toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.icon-toggle input[type="checkbox"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}

.icon-toggle-indicator {
    width: 1.75rem;
    height: 1.75rem;
    border: 1px solid var(--border-primary);
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-secondary);
    background: var(--background-primary);
    cursor: pointer;
    position: relative;
}

.icon-toggle-indicator svg {
    width: 0.95rem;
    height: 0.95rem;
    fill: currentColor;
    display: block;
}

.icon-toggle input[type="checkbox"]:checked + .icon-toggle-indicator {
    color: var(--text-primary);
    border-color: var(--text-secondary);
}

.icon-toggle input[type="checkbox"]:focus-visible + .icon-toggle-indicator {
    outline: 2px solid var(--text-secondary);
    outline-offset: 2px;
}

.icon-toggle-indicator[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    padding: 0.2rem 0.45rem;
    border: 1px solid var(--border-primary);
    border-radius: 4px;
    background: var(--background-secondary);
    color: var(--text-primary);
    font-size: 0.72rem;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s ease;
    z-index: 15;
}

.icon-toggle-indicator[data-tooltip]:hover::after,
.icon-toggle input[type="checkbox"]:focus-visible + .icon-toggle-indicator::after {
    opacity: 1;
}

/* The label beside the pill, and the modal's own spacing for it. */
.bookmark-detail-toggle {
    gap: 0.4rem;
    cursor: pointer;
}

.bookmark-detail-toggle-label {
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
}

.nbm-pin-toggle {
    margin-top: 0.15rem;
}

/* ==== css/search-commands-note.css ==== */
/* :note command modal (AppModal + note-command-modal-inner) */

.modal.note-command-modal-inner {
    max-width: 480px;
    width: min(480px, 92vw);
    padding: 0;
    overflow: hidden;
}

.modal.note-command-modal-inner .modal-header {
    padding: 0.65rem 1rem;
    border-bottom: 1px solid var(--border-primary);
    background: var(--background-secondary);
}

.modal.note-command-modal-inner .modal-title {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.modal.note-command-modal-inner .modal-body {
    padding: 0;
}

.modal.note-command-modal-inner .modal-actions {
    padding: 0.6rem 1rem;
    border-top: 1px solid var(--border-primary);
    background: var(--background-secondary);
}

.note-cmd-body {
    padding: 0.75rem 1rem;
}

.note-cmd-textarea {
    width: 100%;
    box-sizing: border-box;
    background: var(--background-primary);
    color: var(--text-primary);
    border: 1px solid var(--border-primary);
    border-radius: var(--border-radius-sm, 3px);
    padding: 0.6rem 0.75rem;
    font-family: inherit;
    font-size: var(--font-size-text);
    line-height: 1.5;
    resize: vertical;
    outline: none;
    transition: border-color 0.15s;
}

.note-cmd-textarea:focus {
    border-color: var(--accent-info, #60a5fa);
}

.note-cmd-textarea::placeholder {
    color: var(--text-tertiary, var(--text-secondary));
    opacity: 0.7;
}

.note-cmd-hint {
    margin: 0.5rem 0 0;
    font-size: var(--font-size-small);
    color: var(--text-secondary);
}

/* ==== css/status.css ==== */
/* Status Monitoring Styles */

/* Theme-aware status tokens — tuned for contrast on every theme */
body:not(.status-color-lock) {
    --status-offline-fg: var(--accent-error);
    --status-checking-fg: var(--accent-warning);

    --status-offline-bg: color-mix(in srgb, var(--accent-error) 20%, var(--background-primary));
    --status-checking-bg: color-mix(in srgb, var(--accent-warning) 14%, var(--background-primary));

    --status-offline-bg-active: color-mix(in srgb, var(--accent-error) 30%, var(--background-primary));
    --status-checking-bg-active: color-mix(in srgb, var(--accent-warning) 22%, var(--background-primary));

    --status-offline-bar: var(--accent-error);
    --status-offline-ring: color-mix(in srgb, var(--accent-error) 55%, transparent);
    --status-checking-ring: color-mix(in srgb, var(--accent-warning) 48%, transparent);
}

/* Status indicators — colour/background only; avoid opacity/transform so rows keep stable height */
.bookmark-link.status-checking {
    transition: color var(--transition-normal), background-color var(--transition-normal), box-shadow var(--transition-normal);
}

.bookmark-link.status-online {
    position: relative;
    transition: color var(--transition-normal), background-color var(--transition-normal), box-shadow var(--transition-normal);
}

.bookmark-link.status-offline {
    position: relative;
    transition: color var(--transition-normal), background-color var(--transition-normal), box-shadow var(--transition-normal);
}

/* Status colors — offline/checking rows only (idle); hover/selection uses bookmark-row chrome */
body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-offline-fg, var(--accent-error, #ef4444));
    background: var(--status-offline-bg, color-mix(in srgb, var(--accent-error, #ef4444) 24%, var(--background-primary)));
    box-shadow: inset 3px 0 0 var(--status-offline-bar, var(--accent-error, #ef4444));
}

body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-checking-fg, var(--accent-warning, #f59e0b));
    background: var(--status-checking-bg, color-mix(in srgb, var(--accent-warning, #f59e0b) 16%, var(--background-primary)));
}

body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline .bookmark-open,
body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline .bookmark-text,
body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking .bookmark-open,
body:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking .bookmark-text {
    color: inherit;
}

/* Optional: preserve bookmark row colors while still showing status state/ping (idle only) */
body.status-color-lock .bookmark-link.status-online:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body.status-color-lock .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body.status-color-lock .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: inherit;
    background: none;
    box-shadow: none;
    font-weight: inherit;
}

body.status-color-lock .bookmark-link.status-online:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text,
body.status-color-lock .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text,
body.status-color-lock .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text {
    color: var(--text-secondary);
}

/* Status text (ping time) — dedicated grid column; fixed width via bookmarks-list[data-show-ping] */
.status-text {
    opacity: 0.9;
    transition: color 0.3s ease;
    color: var(--text-secondary);
    min-width: 0;
}

.status-text.is-empty {
    visibility: hidden;
}

/* Online status ping time — row stays neutral; badge shows reachability when idle */
.bookmark-link.status-online:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text {
    color: var(--accent-success);
    border-color: color-mix(in srgb, var(--accent-success) 30%, transparent);
}

/* Hover/selection: ping badge matches other row badges (full row uses bookmark chrome) */
.bookmark-link.status-online:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .status-text,
.bookmark-link.status-offline:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .status-text,
.bookmark-link.status-checking:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .status-text {
    color: var(--text-secondary);
    border-color: color-mix(in srgb, var(--accent-primary) 35%, var(--border-secondary));
    background: transparent;
}

/* Offline status text (idle only) */
.bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text {
    color: var(--accent-error);
    border-color: color-mix(in srgb, var(--accent-error) 30%, transparent);
}

/* Checking status text (idle only) */
.bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within) .status-text {
    color: var(--accent-warning);
    border-color: color-mix(in srgb, var(--accent-warning) 30%, transparent);
}

/* Status indicator dots - HIDDEN */
.status-indicator {
    display: none;
}

/* Status indicator styles removed - indicator hidden */

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

/* Configuration toggle for individual bookmarks */
.bookmark-status-toggle {
    font-size: var(--font-size-controls);
}

.bookmark-status-toggle input[type="checkbox"] {
    width: 14px !important;
    height: 14px !important;
    margin-right: 0.25rem;
}

.bookmark-status-toggle label {
    font-size: var(--font-size-controls);
    opacity: 0.8;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    color: var(--text-secondary);
}

/* Status monitoring settings group */
.status-settings-group {
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    padding: 1rem;
    margin-top: 1rem;
    background: var(--background-secondary);
}

.status-settings-info {
    margin-top: 0.5rem;
    margin-left: 1.625rem; /* Align with checkbox text */
}

.status-settings-info small {
    font-size: var(--font-size-controls);
    opacity: 0.7;
    line-height: 1.4;
}

/* Nested setting for ping display */
.status-settings-nested {
    margin-left: 1.625rem;
    margin-top: 0.75rem;
    padding-left: 1rem;
    border-left: 2px solid var(--border-primary);
}

/* Refresh button for manual status check */
.status-refresh-btn {
    margin-left: 0.5rem;
    padding: 0.25rem 0.5rem;
    font-size: var(--font-size-controls);
    font-family: var(--font-family-main);
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    cursor: pointer;
    transition: all 0.2s ease;
    background: var(--background-secondary);
    color: var(--text-secondary);
}

.status-refresh-btn:hover {
    background: var(--background-secondary);
    border-color: var(--text-secondary);
    color: var(--text-primary);
}

/* Status Loading Indicator */
.status-loading-indicator {
    display: none; /* Hidden by default */
    font-family: var(--font-family-main);
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-bold);
    color: var(--accent-warning);
    opacity: 0.8;
    margin-left: 1rem;
    align-items: center;
    gap: 0.25rem;
    white-space: nowrap;
}

.status-loading-indicator.show {
    display: flex;
}

.status-loading-text {
    font-family: var(--font-family-main);
    letter-spacing: 0.05em;
}

.status-loading-dots::after {
    content: '';
    animation: loading-dots 1.5s infinite;
    font-weight: var(--font-weight-bold);
}

@keyframes loading-dots {
    0%, 30% {
        content: '.';
    }
    31%, 60% {
        content: '..';
    }
    61%, 100% {
        content: '...';
    }
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .status-loading-indicator {
        font-size: calc(var(--font-size-controls) * 0.9);
        margin-left: 0.5rem;
    }
}

/* ── Monitor emphasis ───────────────────────────────────────────────────────
   How loudly a monitored bookmark announces itself, chosen in Behavior →
   Status & health and mirrored onto <body> by setupDOM.

   The row always carries data-check-mode="monitor"; only the emphasis differs,
   so switching modes is a repaint rather than a re-render.

     problems (default) — a healthy monitor looks like any other bookmark; only
                          an outage draws the eye, via the status-offline rules
                          above. Nothing extra is needed here.
     always             — an accent edge on every monitor, healthy or not.
     never              — monitoring stays in the Health view, including the
                          outage colouring the other two modes rely on.
*/
body[data-monitor-emphasis="always"] .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link[data-check-mode="monitor"]:not(.status-offline):not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    box-shadow: inset 3px 0 0 var(--monitor-emphasis-bar, var(--accent-primary));
}

/* Deliberately also suppresses the offline colouring: "never stand out" that
   still turned a row red would not be never. The Health view and the header
   badge remain the places an outage is reported. */
body[data-monitor-emphasis="never"] .bookmark-link[data-check-mode="monitor"]:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: inherit;
    background: none;
    box-shadow: none;
}

/* ==== css/select.css ==== */
/* Custom Terminal-Style Select Component */

.custom-select-wrapper {
    position: relative;
    display: inline-block;
    min-width: 0;
}

.page-selector-wrapper .custom-select-wrapper {
    min-width: 200px;
    width: 100%;
}

.custom-select {
    position: relative;
    cursor: pointer;
}

.custom-select-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.375rem 0.5rem;
    border: none;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-size: var(--font-size-text);
    font-family: var(--font-family-main);
    cursor: pointer;
    user-select: none;
    transition: border-color 0.3s ease;
}

.custom-select-trigger:hover {
    opacity: 0.8;
}

.custom-select.open .custom-select-trigger {
    border-color: var(--text-secondary);
}

.custom-select-arrow {
    font-size: var(--font-size-controls);
    margin-left: 0.5rem;
    transition: transform 0.2s ease;
}

.custom-select.open .custom-select-arrow {
    transform: rotate(180deg);
}

.custom-select-options {
    position: fixed;
    border: 1px solid var(--border-primary);
    max-height: 250px;
    overflow-y: auto;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
    z-index: 9999;
    background-color: var(--background-primary);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}

.custom-select-options.is-open {
    opacity: 1;
    visibility: visible;
}

.custom-select-option {
    padding: 0.5rem 0.75rem;
    font-size: var(--font-size-text);
    font-family: var(--font-family-main);
    cursor: pointer;
    transition: background-color 0.15s ease;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-primary);
}

.custom-select-option:hover {
    background-color: var(--background-secondary);
}

.custom-select-option.selected {
    font-weight: var(--font-weight-semibold);
    color: var(--accent-success);
}

.custom-select-option.selected::before {
    content: '>';
    font-weight: var(--font-weight-black);
    margin-right: 0.25rem;
}

.custom-select-option.highlighted {
    font-weight: var(--font-weight-semibold);
}

/* Scrollbar styling for options */
.custom-select-options::-webkit-scrollbar {
    width: 8px;
}

.custom-select-options::-webkit-scrollbar-track {
    background: var(--background-primary);
}

.custom-select-options::-webkit-scrollbar-thumb {
    background: var(--border-primary);
    border-radius: 0;
}

.custom-select-options::-webkit-scrollbar-thumb:hover {
    background: var(--text-secondary);
}

/* Hide original select */
.custom-select-wrapper select {
    display: none;
}

/* ==== css/font-size.css ==== */
/* Font Size System - CSS Variables */

/* Global font for the entire app */
:root {
    --font-family-main: 'Source Code Pro', monospace;
    font-family: var(--font-family-main);
}

/* Font Size Variables - Default (Medium/m - Level 3) */
:root {
    /* Main Categories - Only 5 core variables */
    --font-size-title: 3rem;           /* Dashboard title (big title) */
    --font-size-date: 1.125rem;        /* Date in header */
    --font-size-category: 1.125rem;    /* Category/column titles */
    --font-size-bookmark: 1.25rem;     /* Bookmark links */
    --font-size-controls: 0.875rem;    /* Tabs, buttons, config link */
    --font-size-text: 0.875rem;        /* General text (forms, config, body text, etc.) */
    
    /* Font Weight Variables - 4 core weights */
    --font-weight-normal: 400;         /* Normal text weight */
    --font-weight-semibold: 600;       /* Semibold - labels, emphasis */
    --font-weight-bold: 700;           /* Bold - headings, important text */
    --font-weight-black: 900;          /* Extra bold - titles, strong emphasis */
}

/* Extra Small - xs (Level 0) */
body.font-size-xs {
    --font-size-title: 1.5rem;
    --font-size-date: 0.75rem;
    --font-size-category: 0.75rem;
    --font-size-bookmark: 0.813rem;
    --font-size-controls: 0.625rem;
    --font-size-text: 0.625rem;
}

/* Small - s (Level 1) */
body.font-size-s {
    --font-size-title: 1.75rem;
    --font-size-date: 0.813rem;
    --font-size-category: 0.813rem;
    --font-size-bookmark: 0.938rem;
    --font-size-controls: 0.688rem;
    --font-size-text: 0.688rem;
}

/* Small-Medium - sm (Level 2) */
body.font-size-sm {
    --font-size-title: 2rem;
    --font-size-date: 0.938rem;
    --font-size-category: 0.938rem;
    --font-size-bookmark: 1rem;
    --font-size-controls: 0.75rem;
    --font-size-text: 0.75rem;
}

/* Medium - m (Level 3 - Default) */
body.font-size-m {
    --font-size-title: 3rem;
    --font-size-date: 1.125rem;
    --font-size-category: 1.125rem;
    --font-size-bookmark: 1.25rem;
    --font-size-controls: 0.875rem;
    --font-size-text: 0.875rem;
}

/* Large-Medium - lg (Level 4) */
body.font-size-lg {
    --font-size-title: 3.5rem;
    --font-size-date: 1.25rem;
    --font-size-category: 1.25rem;
    --font-size-bookmark: 1.375rem;
    --font-size-controls: 0.938rem;
    --font-size-text: 0.938rem;
}

/* Large - l (Level 5) */
body.font-size-l {
    --font-size-title: 4rem;
    --font-size-date: 1.375rem;
    --font-size-category: 1.375rem;
    --font-size-bookmark: 1.5rem;
    --font-size-controls: 1rem;
    --font-size-text: 1rem;
}

/* Extra Large - xl (Level 6) */
body.font-size-xl {
    --font-size-title: 4.5rem;
    --font-size-date: 1.5rem;
    --font-size-category: 1.5rem;
    --font-size-bookmark: 1.625rem;
    --font-size-controls: 1.125rem;
    --font-size-text: 1.125rem;
}

/* Extra Large - xl (Level 6) */
body.font-size-xl {
    --font-size-title: 4.5rem;
    --font-size-date: 1.5rem;
    --font-size-category: 1.5rem;
    --font-size-bookmark: 1.625rem;
    --font-size-controls: 1.125rem;
    --font-size-text: 1.125rem;
}

/* Responsive adjustments for font sizes */
@media (max-width: 767px) {
    body.font-size-xl {
        --font-size-title: 3.5rem;
    }
    
    body.font-size-l {
        --font-size-title: 3rem;
    }
    
    body.font-size-lg {
        --font-size-title: 2.5rem;
    }
}

@media (max-width: 479px) {
    body.font-size-xl {
        --font-size-title: 3rem;
    }
    
    body.font-size-l {
        --font-size-title: 2.5rem;
    }
    
    body.font-size-lg {
        --font-size-title: 2.25rem;
    }
    
    body.font-size-m {
        --font-size-title: 2rem;
    }
    
    body.font-size-sm {
        --font-size-title: 1.75rem;
    }
    
    body.font-size-s {
        --font-size-title: 1.5rem;
    }
    
    body.font-size-xs {
        --font-size-title: 1.25rem;
    }
}

/* ==== css/responsive.css ==== */
/* Responsive Design System */

/* General mobile button styles */
.button-container {
    gap: 0.5rem;
}

/* Large Desktop (1200px+) - Default styles already applied */

/* Desktop (992px - 1199px) */
@media (max-width: 1199px) {
    .dashboard-section.section-controls,
    .config-section.section-header {
        padding-top: 1.75rem;
    }
    
    .dashboard-section.section-content {
        padding-bottom: 3rem; /* Space for search button */
    }
    
    .config-section.section-content {
        padding-top: 0.875rem;
        padding-bottom: 1.75rem;
    }
    
    .container {
        /* Roomier clamp() margin (not a percentage) so the columns sit closer
           together, shrinking toward the floor as the window narrows. */
        max-width: 100%;
        padding: 0 clamp(1.5rem, 5vw, 6rem);
    }

    /* Keep the config page shell in step with the dashboard .container at this
       breakpoint so the config header/nav stay aligned with the dashboard. */
    html:has(#config-main) .config-page-shell {
        grid-template-columns: minmax(0, 1fr);
        max-width: 1600px;
        padding-inline: clamp(1.5rem, 5vw, 6rem);
    }

    /* Same for the health shell, so its header/nav stay aligned too. */
    .health-shell {
        max-width: 100%;
        padding-left: clamp(1.5rem, 5vw, 6rem);
        padding-right: clamp(1.5rem, 5vw, 6rem);
    }

    .dashboard-grid {
        gap: 2rem;
    }
    
    .search-container {
        width: min(52rem, calc(100vw - 2.5rem));
        max-width: 100%;
    }
    
    /* No `bottom` here (or in the narrower breakpoints below): the button bar is
       positioned by .button-container, and these buttons are flex children of
       it. The declaration was a leftover from when each button was fixed
       individually. It was inert on the `static` ones, but .search-button
       [data-tooltip] sets position: relative for the tooltip anchor — so the
       one button the JS tooltip system does not manage (fold-all, which keeps
       its data-tooltip attribute) was lifted out of the row by exactly that
       many pixels as soon as a breakpoint applied. */
    .search-button {
        padding: 0.8rem 1rem;
    }
    
    /* Tabs responsive - desktop */
    .tabs {
        flex-wrap: wrap;
    }
    
    /* List items responsive - desktop */
    .page-item,
    .category-item,
    .bookmark-item,
    .finder-item {
        flex-wrap: wrap;
        gap: 0.5rem;
    }
    
    .form-group {
        flex-wrap: wrap;
    }
    
    .config-actions-top {
        flex-wrap: wrap;
        gap: 0.75rem;
    }
}

/* Tablet (768px - 991px) */
@media (max-width: 991px) {
    .dashboard-section.section-controls,
    .config-section.section-header {
        padding-top: 1.5rem;
    }
    
    .dashboard-section.section-content {
        padding-bottom: 3rem; /* Space for search button */
    }
    
    .config-section.section-content {
        padding-top: 0.75rem;
        padding-bottom: 1.5rem;
    }
    
    .container {
        max-width: 95%;
        padding: 0 0.75rem;
    }
    
    .dashboard-grid {
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 1.5rem;
    }

    body[data-layout-version="modern"] .dashboard-grid {
        grid-template-columns: unset !important;
    }

    .dashboard-grid.packed-columns {
        display: flex !important;
        flex-wrap: wrap;
        justify-content: center;
        grid-template-columns: unset !important;
        gap: 1.5rem;
    }

    body[data-layout-version="modern"] .dashboard-grid.packed-columns {
        display: grid !important;
        flex-wrap: unset;
        justify-content: unset;
    }

    .dashboard-grid.packed-columns .dashboard-column {
        flex: 1 1 calc(50% - 0.75rem);
        gap: 1.5rem;
    }

    body[data-layout-version="modern"] .dashboard-grid.packed-columns .dashboard-column {
        flex: unset;
    }
    
    .title {
        font-size: var(--font-size-title);
    }
    
    .header-actions {
        gap: var(--header-control-gap, 0.5rem);
        margin-left: auto;
    }
    
    .page-nav-btn {
        padding: 0.35rem 0.5rem;
        font-size: var(--font-size-controls);
    }
    
    .config-link a {
        font-size: var(--font-size-controls);
    }
    
    .bookmark-link {
        padding: 0.4rem 0;
    }
    
    .config-button {
        padding: 0.75rem 1rem;
    }
    
    .search-container {
        width: min(52rem, calc(100vw - 2rem));
        max-width: 100%;
        padding: 1.25rem 1.5rem 0.875rem 2rem;
    }
    
    .search-button {
        padding: 0.8rem 1rem;
        font-size: var(--font-size-controls);
    }
    
    /* Config page tablet styles */
    .bookmark-item {
        display: grid;
        grid-template-columns: 1fr 1fr 100px 120px 80px;
        gap: 0.75rem;
    }
    
    .finder-item {
        display: grid;
        grid-template-columns: 1fr 1fr 100px 80px;
        gap: 0.75rem;
    }
    
    .category-item {
        display: grid;
        grid-template-columns: 1fr 80px;
    }
    
    .section {
        margin-bottom: 2rem;
    }
    
    /* Colors page - stack vertically on tablet */
    .config-main,
    .custom-themes-main-grid {
        grid-template-columns: 1fr;
        gap: 2rem;
    }
    
    /* Tabs responsive - tablet */
    .tabs {
        flex-wrap: wrap;
    }
    
    .tab-button {
        padding: 0.625rem 1.25rem;
        font-size: var(--font-size-controls);
    }
    
    .config-actions-top {
        flex-wrap: wrap;
        gap: 0.75rem;
    }
}

/* Mobile Large (576px - 767px) */
@media (max-width: 767px) {
    .container {
        padding: 1rem 0.5rem;
    }
    
    .dashboard-grid {
        grid-template-columns: 1fr !important;
        gap: 1.5rem;
    }

    body[data-layout-version="modern"] .dashboard-grid {
        grid-template-columns: unset !important;
    }
    
    .category h3 {
        margin-bottom: 0.75rem;
    }
    
    .bookmark-link {
        padding: 0.35rem 0;
    }
    
    .config-button {
        padding: 0.625rem 0.875rem;
    }
    
    .shortcut-hint {
        bottom: 1rem;
        right: 1rem;
        left: 1rem;
        text-align: center;
        padding: 0.5rem;
    }
    
    .search-container {
        width: calc(100vw - 2rem);
        max-width: 100%;
        padding: 1rem 1.25rem 0.75rem 2rem;
    }
    
    /* Prevent horizontal scroll on small screens */
    .search-prompt,
    .search-query,
    .search-match-name {
        max-width: 100%;
        overflow-x: hidden;
    }
    
    .search-match {
        padding: 0.4rem 0;
    }
    
    .search-button {
        padding: 0.8rem 1rem;
        font-size: var(--font-size-controls);
    }
    
    .button-container {
        width: calc(100% - 2rem);
        justify-content: center;
        bottom: 1rem;
    }
    
    /* Header responsive - mobile large */
    .dashboard-section,
    .config-section {
        padding: 0;
    }
    
    .dashboard-section.section-controls,
    .config-section.section-header {
        padding-top: 1.5rem;
    }

    .dashboard-section.section-controls {
        padding-bottom: 0;
    }

    .config-section.section-header {
        padding-bottom: 1.25rem;
    }
    
    .dashboard-section.section-title,
    .config-section.section-controls {
        padding-top: 0;
        padding-bottom: 0;
    }
    
    .dashboard-section.section-content {
        padding-top: 0;
        padding-bottom: 3rem; /* Space for search button */
    }
    
    .config-section.section-content {
        padding-top: 0.75rem;
        padding-bottom: 1.5rem;
    }
    
    .container {
        padding: 0 0.75rem;
    }
    
    .header-top {
        flex-direction: row;
        align-items: center;
        gap: 0.5rem;
    }

    .date {
        display: none;
    }

    .date-badge-mobile:not(:empty) {
        display: flex;
        align-items: center;
        font-size: calc(var(--font-size-controls) * 0.88);
        font-weight: var(--font-weight-semibold);
        color: var(--text-secondary);
        background: var(--background-secondary);
        border: 1px solid var(--border-primary);
        border-radius: 20px;
        padding: 0.18rem 0.6rem;
        cursor: pointer;
        white-space: nowrap;
        user-select: none;
        transition: border-color 0.12s ease, color 0.12s ease;
        order: -1;
    }

    .date-badge-mobile:not(:empty):hover,
    .date-badge-mobile:not(:empty):focus-visible {
        border-color: var(--accent-primary);
        color: var(--text-primary);
        outline: none;
    }

    .title {
        font-size: var(--font-size-title);
    }

    .header-actions {
        flex-direction: row;
        align-items: center;
        gap: 0.75rem;
        margin-left: auto;
        min-width: 0;
    }

    .header {
        flex-direction: column;
        align-items: center;
        gap: 0.75rem;
    }

    .header .nav-links,
    .header .header-links {
        order: -1;
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
    }

    .header.config-header-top {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
        gap: 0.5rem 0.75rem;
    }

    .header.config-header-top .header-links {
        order: 0;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.75rem 1rem;
    }

    .config-header-top .header-actions {
        margin-left: auto;
    }

    .page-navigation {
        gap: 0.125rem;
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        min-width: 0;
    }

    .page-navigation::-webkit-scrollbar {
        display: none;
    }

    .page-nav-btn {
        scroll-snap-align: start;
        flex-shrink: 0;
    }

    .page-nav-btn {
        padding: 0.3rem 0.45rem;
        font-size: var(--font-size-controls);
    }

    .page-swipe-hint {
        display: flex;
        align-items: center;
        font-size: calc(var(--font-size-controls) * 0.82);
        color: var(--text-tertiary);
        white-space: nowrap;
        flex-shrink: 0;
        opacity: 0;
        animation: swipeHintPulse 2.4s ease-in-out 0.6s 3 forwards;
        pointer-events: none;
        letter-spacing: 0.04em;
    }

    @keyframes swipeHintPulse {
        0%   { opacity: 0; }
        25%  { opacity: 0.7; }
        75%  { opacity: 0.7; }
        100% { opacity: 0; }
    }
    
    .config-link a {
        font-size: var(--font-size-controls);
    }
    
    /* Config page mobile large styles */
    .section {
        margin-bottom: 1.5rem;
    }
    
    .page-selector-wrapper {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }
    
    .page-selector-wrapper label {
        white-space: normal;
    }
    
    .page-selector {
        max-width: 100%;
        width: 100%;
    }
    
    .category-item,
    .bookmark-item,
    .finder-item {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }
    
    .category-item input,
    .bookmark-item input,
    .bookmark-item select,
    .finder-item input {
        width: 100%;
        margin-bottom: 0.5rem;
    }
    
    .config-actions {
        flex-direction: column;
        gap: 0.75rem;
    }
    
    .config-actions .btn {
        width: 100%;
    }
    
    .notification {
        bottom: max(1rem, env(safe-area-inset-bottom));
        right: max(1rem, env(safe-area-inset-right));
        left: auto;
        margin: 0;
        max-width: 320px;
        text-align: left;
    }
    
    /* Modal responsive */
    .modal {
        max-width: 320px;
        width: 95%;
        padding: 1rem 1.25rem;
    }
    
    .modal-body {
        margin-bottom: 1.25rem;
    }
    
    .modal-button {
        padding: 0.375rem 0.75rem;
    }
    
    .modal-button-prefix {
        min-width: 2.5ch;
    }
    
    /* Colors page - stack vertically on mobile */
    .config-main,
    .custom-themes-main-grid {
        grid-template-columns: 1fr;
        gap: 2rem;
    }
    
    .colors-grid {
        gap: 2rem;
    }
    
    /* Tabs responsive - mobile large */
    .tabs {
        flex-wrap: wrap;
        gap: 0;
        top: 65px;
    }
    
    .tab-button {
        padding: 0.5rem 1rem;
        font-size: var(--font-size-controls);
        flex: 1 1 auto;
        min-width: 120px;
    }
    
    .config-actions-top {
        flex-wrap: wrap;
        gap: 0.625rem;
    }
    
    .config-actions-top .btn {
        flex: 1 1 auto;
        min-width: 140px;
    }
}

/* Mobile Small (480px - 575px) */
@media (max-width: 575px) {
    .container {
        padding: 0.75rem 0.375rem;
    }
    
    .dashboard-grid {
        gap: 1.25rem;
    }
    
    .bookmark-link {
        padding: 0.3rem 0;
    }
    
    .config-button {
        padding: 0.5rem 0.75rem;
    }
    
    .search-container {
        width: calc(100% - 2rem);
        max-width: 100%;
        margin: 0 auto;
        padding: 0.875rem 1rem 0.625rem 2rem;
    }
    
    .search-prompt {
        margin-bottom: 0.5rem;
    }
    
    .search-button {
        padding: 0.8rem 1rem;
        font-size: var(--font-size-text);
    }
    
    .button-container {
        width: calc(100% - 2rem);
        justify-content: center;
    }
    
    /* Header responsive - mobile small */
    .dashboard-section,
    .config-section {
        padding: 0;
    }
    
    .dashboard-section.section-controls,
    .config-section.section-header {
        padding-top: 1.25rem;
    }

    .dashboard-section.section-controls {
        padding-bottom: 0;
    }

    .config-section.section-header {
        padding-bottom: 1.125rem;
    }
    
    .dashboard-section.section-title,
    .config-section.section-controls {
        padding-top: 0;
        padding-bottom: 0;
    }
    
    .dashboard-section.section-content {
        padding-top: 0;
        padding-bottom: 3rem; /* Space for search button */
    }
    
    .config-section.section-content {
        padding-top: 0.625rem;
        padding-bottom: 1.25rem;
    }
    
    .container {
        padding: 0 0.5rem;
    }
    
    .header-top {
        flex-direction: row;
        align-items: center;
        gap: 0.5rem;
    }

    .title {
        font-size: var(--font-size-title);
    }

    .header-actions {
        gap: 0.625rem;
        margin-left: auto;
    }
    
    .header {
        flex-direction: column;
        align-items: center;
        gap: 0.625rem;
    }
    
    .header .nav-links,
    .header .header-links {
        order: -1;
        display: flex;
        flex-direction: column;
        gap: 0.625rem;
    }

    .header.config-header-top {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
        gap: 0.5rem 0.625rem;
    }

    .header.config-header-top .header-links {
        order: 0;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.625rem 0.85rem;
    }

    .config-header-top .header-actions {
        margin-left: auto;
    }
    
    .page-nav-btn {
        padding: 0.25rem 0.4rem;
        font-size: var(--font-size-controls);
    }

    .config-link a {
        font-size: var(--font-size-text);
    }
    
    /* Config page mobile small styles */
    .section {
        margin-bottom: 1.25rem;
    }
    
    .form-group {
        margin-bottom: 1rem;
    }
    
    .btn {
        padding: 0.625rem 1rem;
    }
    
    /* Tabs responsive - mobile small */
    .tabs {
        top: auto;
        position: relative;
    }
    
    .tab-button {
        padding: 0.5rem 0.75rem;
        font-size: var(--font-size-controls);
        flex: 1 1 auto;
        min-width: 100px;
    }
    
    .config-actions-top {
        flex-direction: column;
    }
    
    .config-actions-top .btn {
        width: 100%;
    }
}

/* Mobile Extra Small (up to 479px) */
@media (max-width: 479px) {
    .container {
        padding: 0.5rem 0.25rem;
    }
    
    .dashboard-grid {
        gap: 0rem;
    }
    
    .category {
        margin-bottom: 1.5rem;
    }
    
    .category h3 {
        margin-bottom: 0.5rem;
    }
    
    .bookmark-link {
        padding: 0.25rem 0;
    }
    
    .config-button {
        top: 0.5rem;
        right: 0.5rem;
        padding: 0.4rem 0.625rem;
    }
    
    .shortcut-hint {
        padding: 0.375rem;
        bottom: 0.5rem;
        right: 0.5rem;
        left: 0.5rem;
    }
    
    .search-container {
        width: calc(100% - 2rem);
        max-width: 100%;
        margin: 0 auto;
        padding: 0.75rem 0.875rem 0.5rem 2rem;
    }
    
    .search-prompt {
        margin-bottom: 0.5rem;
    }
    
    .search-match {
        padding: 0.3rem 0;
    }
    
    .search-match-shortcut {
        min-width: 2.5ch;
    }
    
    .search-button {
        padding: 0.8rem 1rem;
        font-size: var(--font-size-controls);
    }
    
    .button-container {
        width: calc(100% - 2rem);
        justify-content: center;
    }
    
    .search-button-icon {
        font-size: var(--font-size-controls);
    }
    
    /* Header responsive - mobile extra small */
    .dashboard-section,
    .config-section {
        padding: 0;
    }
    
    .dashboard-section.section-controls,
    .config-section.section-header {
        padding-top: 1rem;
    }

    .dashboard-section.section-controls {
        padding-bottom: 0;
    }

    .config-section.section-header {
        padding-bottom: 1rem;
    }
    
    .dashboard-section.section-title,
    .config-section.section-controls {
        padding-top: 0;
        padding-bottom: 0;
    }
    
    .dashboard-section.section-content {
        padding-top: 0;
        padding-bottom: 3rem; /* Space for search button */
    }
    
    .config-section.section-content {
        padding-top: 0.5rem;
        padding-bottom: 1rem;
    }
    
    .container {
        padding: 0 0.5rem;
    }
    
    .header-top {
        flex-direction: row;
        align-items: center;
        gap: 0.5rem;
    }

    .title {
        font-size: var(--font-size-title);
    }

    .header-actions {
        gap: 0.5rem;
        margin-left: auto;
    }
    
    .header {
        flex-direction: column;
        align-items: center;
        gap: 0.5rem;
    }
    
    .header .nav-links,
    .header .header-links {
        order: -1;
        display: flex;
        flex-direction: column;
        gap: 0.5rem;
    }

    .header.config-header-top {
        flex-direction: row;
        align-items: flex-start;
        justify-content: space-between;
        gap: 0.5rem;
    }

    .header.config-header-top .header-links {
        order: 0;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.5rem 0.75rem;
    }

    .config-header-top .header-actions {
        margin-left: auto;
    }
    
    .page-navigation {
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 0.125rem;
        justify-content: flex-start;
    }

    .page-nav-btn {
        padding: 0.25rem 0.35rem;
        font-size: var(--font-size-controls);
        white-space: nowrap;
    }

    .config-link a {
        font-size: var(--font-size-controls);
        white-space: nowrap;
    }
    
    /* Config page mobile extra small styles */
    .section {
        margin-bottom: 1rem;
    }
    
    .section h2 {
        margin-bottom: 0.75rem;
    }
    
    .form-group {
        margin-bottom: 0.875rem;
    }
    
    .form-control {
        padding: 0.5rem;
    }
    
    .btn {
        padding: 0.5rem 0.75rem;
    }
    
    .config-actions {
        gap: 0.5rem;
    }
    
    .notification {
        bottom: max(0.5rem, env(safe-area-inset-bottom));
        right: max(0.5rem, env(safe-area-inset-right));
        left: auto;
        margin: 0;
        max-width: 280px;
        padding: 0.75rem;
        text-align: left;
    }
    
    .category-item,
    .bookmark-item,
    .finder-item {
        gap: 0.5rem;
    }
    
    .category-item input,
    .bookmark-item input,
    .bookmark-item select,
    .finder-item input {
        margin-bottom: 0.375rem;
    }
    
    /* Modal extra small */
    .modal {
        max-width: 280px;
        width: 90%;
        padding: 0.875rem 1rem;
    }
    
    .modal-body {
        margin-bottom: 1rem;
    }
    
    .modal-actions {
        gap: 0.75rem;
    }
    
    .modal-button {
        padding: 0.3rem 0.5rem;
    }
    
    .modal-button-prefix {
        min-width: 2ch;
        margin-right: 0.75rem;
    }
    
    /* Tabs responsive - mobile extra small */
    .tabs {
        position: relative;
        top: auto;
        flex-direction: column;
    }
    
    .tab-button {
        padding: 0.5rem;
        font-size: var(--font-size-controls);
        text-align: center;
        width: 100%;
        border-bottom: 1px solid var(--border-primary);
    }
    
    .tab-button:last-child {
        border-bottom: none;
    }

    /* Fix for theme and language selectors in config general tab */
    .form-group:has(#theme-select),
    .form-group:has(#language-select) {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }

    .form-group:has(#theme-select) label,
    .form-group:has(#language-select) label {
        min-width: auto;
    }

    .form-group--theme-select .custom-select-wrapper,
    .form-group--theme-select select.config-select-wide {
        min-width: 100%;
        max-width: 100%;
        flex: 1 1 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    /* Swipe hint → show statically, no pulse animation */
    .page-swipe-hint { animation: none !important; opacity: 0.55 !important; }
}

/* ==== css/dashboard-enhancements.css ==== */
/* Dashboard discoverability: header, mobile bar, mini status, a11y, kbd tooltips */

:root {
    --header-chip-radius: 999px;
    --header-chip-pad-block: 0.38rem;
    --header-chip-pad-inline: 0.8rem;
    --layout-radius-xs: 4px;
    --layout-radius-sm: 8px;
    --layout-radius-md: 12px;
    --dashboard-toolbar-stack: 5.75rem;
}

kbd,
.keyboard-cheat-sheet-keys kbd {
    display: inline-block;
    padding: 0.05em 0.35em;
    border: 1px solid color-mix(in srgb, var(--text-secondary) 40%, transparent);
    border-radius: 0.2em;
    background: color-mix(in srgb, var(--background-secondary) 90%, transparent);
    font-family: var(--font-family-main, "Source Code Pro", monospace);
    font-size: 0.92em;
    font-weight: var(--font-weight-bold);
    line-height: 1.3;
    color: var(--text-primary);
}

.kbd-sep,
.kbd-or {
    margin: 0 0.2em;
    color: var(--text-secondary);
    font-size: 0.85em;
    font-weight: var(--font-weight-normal);
}

.toolbar-kbd-tooltip {
    position: fixed;
    z-index: 10050;
    /* --kbd-tooltip-shift nudges the box back inside the window when centring on
       the anchor would push it past the left or right edge. */
    --kbd-tooltip-shift: 0px;
    transform: translate(calc(-50% + var(--kbd-tooltip-shift)), calc(-100% - 8px));
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    padding: 0.35rem 0.55rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.3rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    pointer-events: none;
    white-space: nowrap;
    visibility: hidden;
    opacity: 0;
}

.toolbar-kbd-tooltip.is-visible {
    display: flex;
    visibility: visible;
    opacity: 1;
}

/* Header icons: tooltip appears BELOW the button, because there is no room
   above them at the top of the window. */
.toolbar-kbd-tooltip--below {
    transform: translate(calc(-50% + var(--kbd-tooltip-shift)), 8px);
}

/* Side rail: tooltip appears to the RIGHT of the button */
.toolbar-kbd-tooltip--side-rail {
    transform: translateY(-50%);
}

.toolbar-kbd-tooltip-label {
    font-size: calc(var(--font-size-controls) * 0.82);
    color: var(--text-secondary);
    text-transform: lowercase;
}

.toolbar-kbd-tooltip-keys {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    flex-wrap: wrap;
    justify-content: center;
}

/*
 * These chips name the same shortcuts as the toolbar buttons at the bottom of
 * the screen, so they carry that button's fill. The bare `kbd` rule in
 * enhanced-features.css loads later and would otherwise win with
 * --background-primary, which reads as a different, denser block here.
 */
#toolbar-kbd-tooltip .toolbar-kbd-tooltip-keys kbd {
    background: color-mix(in srgb, var(--background-secondary) 74%, transparent);
    border-color: var(--border-primary);
}

/* Dashboard discoverability: header, mobile bar, mini status, a11y */

.skip-to-content {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 10000;
    padding: 0.5rem 1rem;
    background: var(--bg-primary, #000);
    color: var(--text-primary, #fff);
    border: 1px solid var(--text-primary);
    font-family: var(--font-family-main);
    text-decoration: none;
}

.skip-to-content:focus-visible {
    left: 0.5rem;
    top: 0.5rem;
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    .quick-add-modal-header-actions kbd {
        display: none;
    }
}

/* Dashboard discoverability: header, mobile bar, mini status */

.header-top {
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
}

.header-top-primary {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    flex: 1 1 12rem;
    min-width: 0;
}

.dashboard-mini-status {
    display: none;
    font-size: calc(var(--font-size-controls) * 0.95);
    color: var(--text-tertiary, var(--text-secondary));
    font-family: var(--font-family-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.dashboard-mini-status .mini-sep {
    opacity: 0.45;
    margin: 0 0.35em;
}

body[data-layout-version="classic"] .dashboard-mini-status,
body[data-layout-version="classic"] .status-loading-indicator.show,
body[data-layout-version="classic"] .date-badge-mobile:not(:empty),
body[data-layout-version="classic"] .page-swipe-hint {
    padding: var(--header-chip-pad-block, 0.38rem) var(--header-chip-pad-inline, 0.8rem);
    border-radius: var(--header-chip-radius, 999px);
    border: 1px solid color-mix(in srgb, var(--text-secondary) 35%, transparent);
    background: color-mix(in srgb, var(--background-secondary) 55%, transparent);
}

/* Pages overview icon chrome lives in dashboard.css (.pages-link--icon), shared
   with inbox, health, and config; spacing is .header-actions gap throughout. */

.search-button-labeled {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.15rem;
    min-width: 2.75rem;
    padding: 0.55rem 0.45rem !important;
}

.search-button-label {
    display: none;
    font-size: 0.58rem;
    line-height: 1;
    text-transform: lowercase;
    color: var(--text-secondary);
    font-family: var(--font-family-main);
}

.search-flow-hint .sfh-seg-swipe.hidden {
    display: none;
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    .search-button-labeled .search-button-label {
        display: block;
    }

    .dashboard-mini-status {
        display: block;
    }

    .search-flow-hint .sfh-seg-swipe.hidden {
        display: inline;
    }

    .search-button[data-tooltip]::after {
        display: none !important;
    }
}

@media (max-width: 575px) {
    .date {
        display: none;
    }
}

.save-status-indicator.is-saved-flash {
    animation: config-saved-flash 1.4s ease;
}

.search-button.first-bookmark-pulse {
    animation: first-bookmark-pulse 1s ease 3;
}

@keyframes first-bookmark-pulse {
    0%, 100% { box-shadow: 0 0 0 0 transparent; }
    50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-success, #00ff9c) 55%, transparent); }
}

@keyframes config-saved-flash {
    0% { opacity: 0.5; transform: scale(0.96); }
    30% { opacity: 1; transform: scale(1.02); color: var(--accent-success, #00ff9c); }
    100% { opacity: 1; transform: scale(1); }
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    :root {
        --dashboard-toolbar-stack: 6.75rem;
    }
}

:is(
    .dashboard-search-promo,
    .dashboard-g-jump-promo,
    .dashboard-grid-kbd-promo,
    .dashboard-smart-collection-promo,
    .dashboard-feature-promo
) kbd {
    border-radius: 0.2em;
}

/* ==== css/skeleton-loading.css ==== */
/* Shared skeleton placeholders while body.loading */

body.loading {
    overflow-x: hidden;
}

.skeleton-root {
    display: none;
    pointer-events: none;
    user-select: none;
}

body.loading .skeleton-root {
    display: block;
}

body.loading .skeleton-dashboard.skeleton-root,
body.loading .skeleton-health-summary.skeleton-root,
body.loading .skeleton-colors-grid.skeleton-root {
    display: grid;
}

body.loading .skeleton-hide-while-loading {
    visibility: hidden !important;
}

body.loading #config-main > :not([data-skeleton-root]),
body.loading .colors-main > :not([data-skeleton-root]) {
    visibility: hidden;
}

.skeleton-shimmer {
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--text-secondary, #888) 12%, transparent) 0%,
        color-mix(in srgb, var(--text-secondary, #888) 22%, transparent) 50%,
        color-mix(in srgb, var(--text-secondary, #888) 12%, transparent) 100%
    );
    background-size: 200% 100%;
    animation: skeleton-shimmer 0.75s ease-in-out infinite;
    border-radius: 2px;
}

@keyframes skeleton-shimmer {
    0% {
        background-position: 100% 0;
    }
    100% {
        background-position: -100% 0;
    }
}

.skeleton-line {
    height: 0.85rem;
    margin-bottom: 0.5rem;
}

.skeleton-line--sm {
    height: 0.65rem;
    width: 40%;
}

.skeleton-line--title {
    height: 1.1rem;
    width: 55%;
    margin-bottom: 0.75rem;
}

.skeleton-line--wide {
    width: 85%;
}

.skeleton-line--pill {
    height: 1.5rem;
    width: 4.5rem;
    border-radius: 999px;
    display: inline-block;
    margin-right: 0.5rem;
}

/* Dashboard */
.skeleton-dashboard {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1.5rem;
    width: 100%;
    padding: 0.25rem 0;
}

.skeleton-dashboard-col {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.skeleton-bookmark-row {
    height: 1.35rem;
    width: 100%;
}

.skeleton-bookmark-row--short {
    width: 72%;
}

/* Config */
.skeleton-config-panel {
    padding: 0.5rem 0 2rem;
}

.skeleton-config-cards {
    display: grid;
    gap: 1rem;
    max-width: 720px;
}

.skeleton-config-card {
    border: 1px solid color-mix(in srgb, var(--text-secondary, #888) 25%, transparent);
    padding: 1rem;
    min-height: 5rem;
}

/* Health */
.skeleton-health-summary {
    display: grid;
    grid-template-columns: repeat(9, minmax(0, 1fr));
    gap: 6px;
    margin-bottom: 0.75rem;
}

.skeleton-health-card {
    min-height: 2.35rem;
    border: 1px solid color-mix(in srgb, var(--text-secondary, #888) 25%, transparent);
    padding: 0.35rem 0.45rem;
}

.skeleton-health-issues {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.skeleton-health-row {
    height: 2.75rem;
    width: 100%;
}

/* Colors */
.skeleton-colors-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1rem;
}

.skeleton-colors-group {
    min-height: 8rem;
    border: 1px solid color-mix(in srgb, var(--text-secondary, #888) 25%, transparent);
    padding: 0.75rem;
}

.skeleton-header-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.35rem;
}

@media (prefers-reduced-motion: reduce) {
    .skeleton-shimmer {
        animation: none;
        background: color-mix(in srgb, var(--text-secondary, #888) 18%, transparent);
    }
}

body.no-animations .skeleton-shimmer {
    animation: none;
    background: color-mix(in srgb, var(--text-secondary, #888) 18%, transparent);
}

/* ==== css/dashboard-quickstart.css ==== */
/*
 * Quick-start card (checklist + compact first-run setup).
 * Non-blocking, bottom-left, theme-driven. Mirrors feature-spotlight conventions
 * so it reads as part of the same system.
 */

.quickstart-card {
    position: fixed;
    left: max(1rem, env(safe-area-inset-left));
    bottom: max(1rem, env(safe-area-inset-bottom));
    width: 340px;
    max-width: calc(100vw - 2rem);
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.5rem;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
    z-index: 2147482800;
    opacity: 0;
    visibility: hidden;
    transform: translateY(12px);
    transition: opacity 0.26s ease, visibility 0.26s ease, transform 0.26s ease;
    overflow: hidden;
    font-family: var(--font-family-main, inherit);
}

.quickstart-card.show {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.quickstart-stripe {
    height: 3px;
    background: var(--accent-primary);
}

.quickstart-inner {
    padding: 0.875rem 1rem 0.9rem;
}

.quickstart-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.quickstart-title {
    font-size: var(--font-size-controls, 0.82rem);
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 0.35rem;
    line-height: 1.3;
}

.quickstart-head .quickstart-title {
    margin-bottom: 0;
}

.quickstart-text {
    font-size: var(--font-size-small, 0.72rem);
    color: var(--text-secondary);
    margin: 0 0 0.6rem;
    line-height: 1.5;
}

.quickstart-close {
    flex-shrink: 0;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.2rem;
    border-radius: 0.25rem;
}

.quickstart-close:hover,
.quickstart-close:focus-visible {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--text-primary) 8%, transparent);
}

/* ---- Checklist ---- */

.quickstart-progress {
    font-size: var(--font-size-small, 0.7rem);
    color: var(--text-secondary);
    margin: 0.4rem 0 0.55rem;
    letter-spacing: 0.02em;
}

.quickstart-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.quickstart-item {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
}

/* Actionable rows: the button becomes the flex row so the layout matches
   a plain item exactly. */
.quickstart-item.is-actionable {
    display: block;
}

.quickstart-item-action {
    display: flex;
    align-items: flex-start;
    gap: 0.55rem;
    width: 100%;
    margin: -0.15rem -0.3rem;
    padding: 0.15rem 0.3rem;
    border: 0;
    border-radius: 5px;
    background: none;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.quickstart-item-action:hover,
.quickstart-item-action:focus-visible {
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
    outline: none;
}

.quickstart-item-action:focus-visible {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 35%, transparent);
}

/* Underline only while not done — .is-done owns text-decoration for the
   strikethrough, and the shorthand would otherwise cancel it. */
.quickstart-item.is-actionable:not(.is-done) .quickstart-item-label {
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--accent-primary) 45%, transparent);
    text-underline-offset: 2px;
}

.quickstart-check {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    border-radius: 999px;
    border: 1.5px solid var(--border-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    transition: background 0.2s ease, border-color 0.2s ease;
}

.quickstart-item.is-done .quickstart-check {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
}

.quickstart-check svg {
    width: 11px;
    height: 11px;
    stroke: currentColor;
    fill: none;
    stroke-width: 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.quickstart-item-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.quickstart-item-label {
    font-size: var(--font-size-small, 0.74rem);
    color: var(--text-primary);
    line-height: 1.35;
}

.quickstart-item.is-done .quickstart-item-label {
    color: var(--text-secondary);
    text-decoration: line-through;
    text-decoration-color: color-mix(in srgb, var(--text-secondary) 55%, transparent);
}

.quickstart-item-hint {
    font-size: var(--font-size-small, 0.66rem);
    color: var(--text-tertiary, var(--text-secondary));
    line-height: 1.35;
    margin-top: 0.05rem;
}

.quickstart-card.is-complete .quickstart-stripe {
    background: var(--accent-success, var(--accent-primary));
}

/* ---- Compact setup card ---- */

.quickstart-field {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 0.7rem;
}

/* [hidden] must win over the flex display above (e.g. weather location field). */
.quickstart-card [hidden] {
    display: none !important;
}

.quickstart-field > span,
.quickstart-fieldset legend {
    font-size: var(--font-size-small, 0.7rem);
    font-weight: 600;
    color: var(--text-primary);
}

.quickstart-select,
.quickstart-input {
    width: 100%;
    padding: 0.4rem 0.5rem;
    font-family: inherit;
    font-size: var(--font-size-small, 0.74rem);
    color: var(--text-primary);
    background: var(--background-primary);
    border: 1px solid var(--border-primary);
    border-radius: 0.35rem;
}

.quickstart-setup-fields {
    max-height: 46vh;
    overflow-y: auto;
    margin-bottom: 0.25rem;
}

.quickstart-field-hint {
    font-size: var(--font-size-small, 0.66rem);
    color: var(--text-tertiary, var(--text-secondary));
    line-height: 1.4;
    margin: 0 0 0.35rem;
}

.quickstart-fieldset {
    border: none;
    margin: 0 0 0.75rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.quickstart-fieldset legend {
    margin-bottom: 0.3rem;
    padding: 0;
}

.quickstart-radio {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: var(--font-size-small, 0.74rem);
    color: var(--text-primary);
    cursor: pointer;
}

.quickstart-radio input {
    accent-color: var(--accent-primary);
}

/* Starting-point step: two stacked option cards with a label + description. */
.quickstart-startpoint {
    gap: 0.5rem;
}

.quickstart-radio-block {
    align-items: flex-start;
    gap: 0.55rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--border-primary);
    border-radius: 8px;
    background: var(--background-secondary);
    transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.quickstart-radio-block input {
    margin-top: 0.15rem;
    flex-shrink: 0;
}

.quickstart-radio-block:has(input:checked) {
    border-color: var(--accent-primary);
    box-shadow: inset 0 0 0 1px var(--accent-primary);
}

.quickstart-radio-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.quickstart-radio-label {
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-primary);
}

.quickstart-radio-hint {
    font-size: var(--font-size-small, 0.66rem);
    color: var(--text-tertiary, var(--text-secondary));
    line-height: 1.4;
}

.quickstart-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 0.35rem;
}

.quickstart-btn {
    font-family: inherit;
    font-size: var(--font-size-small, 0.74rem);
    padding: 0.4rem 0.85rem;
    border-radius: 0.35rem;
    border: 1px solid var(--border-primary);
    cursor: pointer;
    background: var(--background-primary);
    color: var(--text-primary);
}

.quickstart-btn-ghost {
    background: transparent;
}

.quickstart-btn-primary {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: #fff;
    font-weight: 600;
}

.quickstart-btn:hover,
.quickstart-btn:focus-visible {
    filter: brightness(1.05);
}

@media (prefers-reduced-motion: reduce) {
    .quickstart-card {
        transition: opacity 0.01s linear;
        transform: none;
    }
}

/* On small screens, span the width so it doesn't crowd the corner. */
@media (max-width: 560px) {
    .quickstart-card {
        left: 0.75rem;
        right: 0.75rem;
        width: auto;
        max-width: none;
    }
}

/* ── Notice cards ───────────────────────────────────────────────────────
   The bottom-left invitations (analytics, side rail, and any future one) all
   reuse .quickstart-card for placement and chrome; these are the shared parts
   of the body. Built by NoticeCard.define — see static/js/notice-card.js.
   Previously duplicated per card, which is how they drifted apart. */
.notice-card-text {
    margin: 0.35rem 0 0;
    font-size: var(--font-size-small, 0.72rem);
    color: var(--text-secondary);
    line-height: 1.5;
}

/* A footnote rather than part of the pitch: quieter than the body text so it
   reads as a caveat rather than a second paragraph. */
.notice-card-caveat {
    margin: 0.5rem 0 0;
    padding-left: 0.55rem;
    border-left: 2px solid var(--border-color, rgba(128, 128, 128, 0.35));
    font-size: var(--font-size-small, 0.72rem);
    color: var(--text-muted, var(--text-secondary));
    line-height: 1.45;
    opacity: 0.9;
}

/* Why an action failed, kept on the card rather than in a toast that fades
   before it can be read. Styled like the caveat, in the error colour. */
.notice-card-error {
    margin: 0.5rem 0 0;
    padding-left: 0.55rem;
    border-left: 2px solid var(--accent-error, #c0392b);
    font-size: var(--font-size-small, 0.72rem);
    color: var(--accent-error, #c0392b);
    line-height: 1.45;
}

.notice-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.8rem;
}

/* Shown only after the rail is applied: the command that moves it again,
   for the one person who has just proved they care where the bar sits. */
.side-rail-notice-hint {
    margin: 0.6rem 0 0;
    width: 100%;
    font-size: var(--font-size-small, 0.72rem);
    color: var(--text-tertiary, var(--text-secondary));
    line-height: 1.5;
}

.side-rail-notice-hint kbd {
    font-family: var(--font-family-main);
    font-size: 0.68rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 3px;
    padding: 0.05rem 0.3rem;
    color: var(--text-secondary);
}

/* The shared .whats-new-modal shell only scrolls once it hits max-height; this
   modal is shorter than that, so cap the body itself or the last paragraph runs
   under the buttons. */
.analytics-notice-modal .modal-body {
    /* Roomy enough that the three sections normally fit whole; scrolls only on
       short viewports rather than clipping a line mid-sentence. */
    max-height: min(72vh, 40rem);
    overflow-y: auto;
    /* Overlay-style scrollbars hide until you scroll, so the cut-off text reads
       as clipped rather than scrollable. Keep the track visible instead. */
    scrollbar-width: thin;
    scrollbar-gutter: stable;
}

.analytics-notice-modal .modal-body::-webkit-scrollbar {
    width: 8px;
}

.analytics-notice-modal .modal-body::-webkit-scrollbar-thumb {
    background: var(--border-primary);
    border-radius: 4px;
}

/* Modal body: same rhythm as the what's-new release sections. */
.analytics-notice-modal-body p {
    margin: 0 0 1rem;
    line-height: 1.6;
    color: var(--text-secondary);
}

.analytics-notice-modal-body p:last-child {
    margin-bottom: 0;
}

.analytics-notice-heading {
    margin: 0 0 0.35rem;
    font-size: var(--font-size-text, 0.85rem);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--text-primary);
}

.analytics-notice-modal-body .analytics-notice-heading:not(:first-child) {
    margin-top: 1.25rem;
}

/* ─── Modern layout ─────────────────────────────────────────────────────────
   Scoped to body[data-layout-version="modern"]; classic above is untouched.
   Tokens come from layout-modern-tokens.css.
   ------------------------------------------------------------------------- */

/* The card floats over the dashboard, so it follows the overlay grammar in
   overlays-modern.css (rounded, tinted surface, layered shadow) rather than the
   flat panel treatment the in-page views use. */
body[data-layout-version="modern"] .quickstart-card {
    border-radius: var(--layout-radius-lg);
    border-color: var(--layout-surface-border);
    background: var(--layout-surface);
    box-shadow: var(--layout-shadow-lg);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

/* The stripe spans the full width at the very top of the card, so a rounded
   card clips its upper corners. Round its own top edge to match. */
body[data-layout-version="modern"] .quickstart-stripe {
    border-radius: var(--layout-radius-lg) var(--layout-radius-lg) 0 0;
}

body[data-layout-version="modern"] .quickstart-item-action {
    border-radius: var(--layout-radius-sm);
    transition: background-color var(--layout-transition);
}

body[data-layout-version="modern"] .quickstart-item-action:focus-visible {
    outline: var(--layout-focus-ring);
    outline-offset: 1px;
    box-shadow: none;
}

body[data-layout-version="modern"] .quickstart-close {
    border-radius: var(--layout-radius-sm);
    transition:
        background-color var(--layout-transition),
        color var(--layout-transition);
}

body[data-layout-version="modern"] .quickstart-close:focus-visible {
    outline: var(--layout-focus-ring);
    outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
    body[data-layout-version="modern"] .quickstart-item-action,
    body[data-layout-version="modern"] .quickstart-close {
        transition: none;
    }
}

/* ==== css/dashboard-tag-cloud.css ==== */
/* Dashboard tag word cloud — / FAB + anchored modal (desktop / wide layout only) */

.dashboard-tag-cloud-wrap {
    position: fixed;
    inset: 0;
    z-index: 1001;
    display: none;
    pointer-events: none;
    overflow: visible;
}

body[data-show-tag-cloud-button="true"] .dashboard-tag-cloud-wrap.is-eligible {
    display: block;
}

body[data-show-tag-cloud-button="false"] #tag-cloud-toggle-btn,
#tag-cloud-toggle-btn:not(.is-eligible) {
    display: none !important;
}

/* / FAB — fixed like launcher / what's new; same palette as toolbar buttons */
.tag-cloud-toggle-btn.search-button {
    position: fixed;
    z-index: 1002;
    left: var(--corner-fab-edge);
    bottom: calc(var(--corner-fab-edge) + var(--corner-fab-height) + var(--corner-fab-gap));
    padding: 0.62rem 0.82rem;
    pointer-events: auto;
}

.tag-cloud-toggle-btn .search-button-icon {
    animation: btnIconPulse 10.8s ease-in-out infinite;
    animation-delay: 6.4s;
}

body.no-animations .tag-cloud-toggle-btn .search-button-icon {
    animation: none !important;
}

.tag-cloud-toggle-btn.is-active {
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

.tag-cloud-toggle-btn.is-active .search-button-icon {
    color: var(--accent-primary);
}

.tag-cloud-toggle-btn[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    max-width: min(14rem, calc(100vw - 2 * var(--corner-fab-edge)));
    white-space: normal;
    text-align: center;
    line-height: 1.35;
    padding: 0.28rem 0.5rem;
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 0.3rem;
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: calc(var(--font-size-controls) * 0.85);
    font-weight: var(--font-weight-normal);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
    z-index: 1003;
}

.tag-cloud-toggle-btn[data-tooltip]:hover::after {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%);
}

@media (pointer: coarse) {
    .tag-cloud-toggle-btn[data-tooltip]::after {
        display: none;
    }
}

/* Backdrop (click outside) */
.tag-cloud-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.22);
    opacity: 0;
    transition: opacity 0.18s ease;
    pointer-events: none;
}

.tag-cloud-modal-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
}

body[data-tag-filter-active="true"] .tag-cloud-modal-backdrop.is-open {
    pointer-events: none;
}

/* Anchored modal — matches dashboard button surfaces */
.tag-cloud-modal {
    position: fixed;
    z-index: 1002;
    height: auto;
    max-height: min(88vh, var(--tag-cloud-modal-max-height, 88vh));
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 88%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-radius: 0.65rem;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
    opacity: 0;
    transform: translateY(8px) scale(0.97);
    transform-origin: bottom left;
    transition:
        opacity 0.18s ease,
        transform 0.22s ease;
    pointer-events: auto;
    overflow: hidden;
}

.tag-cloud-modal.is-open {
    opacity: 1;
    transform: translateY(0) scale(1);
}

.tag-cloud-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.55rem 0.65rem 0.35rem;
    border-bottom: 1px solid var(--border-primary);
    flex-shrink: 0;
}

.tag-cloud-modal-title {
    font-size: var(--font-size-controls);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
}

.tag-cloud-modal-close {
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-tertiary);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    padding: 0.15rem 0.35rem;
    border-radius: 0.35rem;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.tag-cloud-modal-close:hover {
    color: var(--accent-primary);
    border-color: var(--border-primary);
    background: color-mix(in srgb, var(--background-primary) 94%, transparent);
}

.tag-cloud-modal-body {
    flex: 0 1 auto;
    overflow-y: hidden;
    padding: 1rem 0.85rem 0.75rem;
    min-height: 4.5rem;
    scrollbar-width: thin;
}

.tag-cloud-modal-body.is-scrollable {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* Word cloud: wrapped rows, accent palette, gentle drift */
.tag-cloud-wordcloud {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
    justify-content: center;
    align-items: baseline;
    gap: 0.55rem 0.75rem;
    text-align: center;
    line-height: 1.35;
}

@keyframes tagCloudWordEnter {
    from {
        opacity: 0;
        transform: rotate(var(--tag-rotate, 0deg)) translateY(6px) scale(0.92);
    }
    to {
        opacity: 1;
        transform: rotate(var(--tag-rotate, 0deg)) translateY(0) scale(1);
    }
}

@keyframes tagCloudWordDrift {
    0%,
    100% {
        transform: rotate(var(--tag-rotate, 0deg)) translateY(0);
    }
    50% {
        transform: rotate(var(--tag-rotate, 0deg)) translateY(-2px);
    }
}

.tag-cloud-word {
    display: inline-flex;
    align-items: baseline;
    gap: 0.1em;
    border: none;
    background: transparent;
    font-family: var(--font-family-main);
    font-size: calc(0.82rem + var(--tag-scale, 0.5) * 1.55rem);
    font-weight: calc(500 + var(--tag-scale, 0.5) * 300);
    padding: 0.2em 0.28em;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    letter-spacing: 0.02em;
    white-space: nowrap;
    transition:
        color 0.15s ease,
        text-shadow 0.15s ease,
        transform 0.2s ease;
}

.tag-cloud-wordcloud--live .tag-cloud-word {
    animation:
        tagCloudWordEnter 0.32s ease backwards,
        tagCloudWordDrift 4.5s ease-in-out infinite;
    animation-delay:
        calc(var(--tag-index, 0) * 0.025s),
        calc(0.35s + var(--tag-index, 0) * 0.11s);
}

body.no-animations .tag-cloud-wordcloud--live .tag-cloud-word {
    animation: none !important;
}

.tag-cloud-word-hash {
    font-weight: var(--font-weight-bold);
    font-size: 0.9em;
    color: color-mix(in srgb, var(--accent-primary) 82%, var(--text-secondary));
}

.tag-cloud-word-label {
    line-height: 1.2;
    color: color-mix(
        in srgb,
        var(--text-secondary) calc((1 - var(--tag-scale, 0.5)) * 45%),
        var(--accent-primary) calc(25% + var(--tag-scale, 0.5) * 55%)
    );
}

.tag-cloud-word--tier-xl .tag-cloud-word-label {
    color: var(--accent-primary);
}

.tag-cloud-word--tier-lg .tag-cloud-word-label {
    color: color-mix(in srgb, var(--accent-primary) 88%, var(--text-primary));
}

.tag-cloud-word--tier-xs .tag-cloud-word-label {
    color: var(--text-secondary);
}

.tag-cloud-word--tier-xl {
    letter-spacing: 0.03em;
}

.tag-cloud-word:hover {
    transform: rotate(var(--tag-rotate, 0deg)) scale(1.06) translateY(-1px);
}

.tag-cloud-word:hover .tag-cloud-word-hash,
.tag-cloud-word:hover .tag-cloud-word-label {
    color: var(--accent-primary);
    text-shadow: 0 0 12px color-mix(in srgb, var(--accent-primary) 45%, transparent);
}

.tag-cloud-word.is-selected .tag-cloud-word-hash,
.tag-cloud-word.is-selected .tag-cloud-word-label {
    color: var(--accent-primary);
}

.tag-cloud-word.is-selected .tag-cloud-word-label {
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

.tag-cloud-word:focus,
.tag-cloud-word:focus-visible,
.tag-cloud-word.is-keyboard-focused {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.tag-cloud-modal-empty {
    margin: 0;
    font-size: var(--font-size-small);
    color: var(--text-tertiary);
    text-align: center;
}

.tag-cloud-modal-footer {
    padding: 0.35rem 0.65rem 0.55rem;
    flex-shrink: 0;
}

.tag-cloud-clear-filter {
    width: 100%;
    border: 1px solid var(--border-primary);
    background: color-mix(in srgb, var(--background-secondary) 74%, transparent);
    color: var(--text-secondary);
    font-family: var(--font-family-main);
    font-size: var(--font-size-small);
    padding: 0.35rem 0.5rem;
    border-radius: 0.65rem;
    cursor: pointer;
    transition:
        background-color 0.2s ease,
        border-color 0.2s ease,
        color 0.2s ease,
        transform 0.2s ease,
        box-shadow 0.2s ease;
}

.tag-cloud-clear-filter:hover {
    background: color-mix(in srgb, var(--background-primary) 94%, transparent);
    border-color: var(--accent-primary);
    color: var(--text-primary);
    transform: translateY(-1px);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
}

.tag-cloud-clear-filter:focus,
.tag-cloud-clear-filter:focus-visible,
.tag-cloud-clear-filter.is-keyboard-focused {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

/* Dock corners */
body[data-button-position="bottom-left"] .tag-cloud-toggle-btn.search-button {
    left: auto;
    right: var(--corner-fab-edge);
}

body[data-button-position="bottom-left"] .tag-cloud-modal {
    transform-origin: bottom right;
}

body[data-button-position="bottom-right"] .tag-cloud-toggle-btn.search-button {
    left: var(--corner-fab-edge);
    right: auto;
}

body[data-button-position="bottom-right"] .tag-cloud-modal {
    transform-origin: bottom left;
}

body[data-button-position="side-left"] .tag-cloud-modal {
    transform-origin: top left;
}

/* ==== css/feed-row.css ==== */
/* The bookmark feed row, shared by Health, Inbox and Config → Bookmarks.
 *
 * The three used to carry their own copy of this rule — `.health-view-item`,
 * `.inbox-item` and `.config-bm-item` — and the copies had drifted into being
 * byte-identical, which is the worst of both: one design, three places to change
 * it, and no way to tell whether a difference was meant.
 *
 * What genuinely differs between the three is expressed as modifiers below: the
 * checkbox column Health keeps in the grid, and the coloured left edge each view
 * uses for its own state (unread, broken, ticked).
 *
 * Loaded before health-view.css, config-view.css and dashboard-inbox.css so
 * those files can still override where a view really needs it.
 */

.feed-row {
    position: relative;
    display: grid;
    grid-template-columns: 3rem 1fr;
    gap: 0.85rem;
    padding: 0.75rem 0.85rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-sm, 8px);
    background: var(--background-secondary);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Health keeps the checkbox in the grid rather than floating it over the icon:
   its rows are scanned in bulk, so the column is always there and only fades. */
.feed-row--with-select {
    grid-template-columns: 1.1rem 3rem 1fr;
}

.feed-row:hover {
    border-color: color-mix(in srgb, var(--accent-primary) 42%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 7%, var(--background-secondary));
}

.feed-row.keyboard-selected {
    border-color: var(--accent-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 28%, transparent);
    background: color-mix(in srgb, var(--accent-primary) 9%, var(--background-secondary));
}

/* The flash after jumping to a row from somewhere else. */
.feed-row--highlight {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 35%, transparent);
}

/* Classic layout has no focus ring on the row at all — the keyboard cursor is
   drawn by .keyboard-selected, but Tab-ing to a row with tabindex="-1" showed
   nothing. Modern layout already had this; now both do. */
.feed-row:focus-visible {
    outline: var(--layout-focus-ring, 2px solid color-mix(in srgb, var(--accent-primary) 72%, transparent));
    outline-offset: 2px;
}

/* The state edge. Each view names its own state; the shape is shared. */
.feed-row--edge-accent {
    border-left: 3px solid var(--accent-primary);
}

.feed-row--edge-error {
    border-left: 3px solid var(--accent-error);
}

.feed-row--edge-warning {
    border-left: 3px solid var(--accent-warning);
}

/* Rounded corners would clip a left border, so modern redraws the edge as an
   inset shadow. Kept here with the edge it belongs to rather than repeated in
   each view's modern block. */
body[data-layout-version="modern"] .feed-row {
    border-radius: var(--layout-radius-md, 12px);
    border-color: var(--layout-surface-border);
    background: var(--layout-surface);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .feed-row--edge-accent,
body[data-layout-version="modern"] .feed-row--edge-error,
body[data-layout-version="modern"] .feed-row--edge-warning {
    border-left-width: 1px;
}

body[data-layout-version="modern"] .feed-row--edge-accent {
    box-shadow: var(--layout-shadow-sm), inset 3px 0 0 0 var(--accent-primary);
}

body[data-layout-version="modern"] .feed-row--edge-error {
    box-shadow: var(--layout-shadow-sm), inset 3px 0 0 0 var(--accent-error);
}

body[data-layout-version="modern"] .feed-row--edge-warning {
    box-shadow: var(--layout-shadow-sm), inset 3px 0 0 0 var(--accent-warning);
}

/* The feed itself: a column of cards, no dividers and no striping — the card
   border and the gap do the separating. */
.feed-list {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

/* The row's action bar, revealed on hover, focus or the keyboard cursor.
   grid-template-rows rather than height, so it animates from nothing to its
   own content height without a magic number. */
.feed-row-actions {
    display: grid;
    grid-template-rows: 0fr;
    margin-top: 0;
    opacity: 0;
    transition:
        grid-template-rows 0.14s ease,
        opacity 0.12s ease,
        margin-top 0.14s ease;
}

.feed-row-actions > * {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    min-height: 0;
    overflow: hidden;
}

.feed-row:hover .feed-row-actions,
.feed-row:focus-within .feed-row-actions,
.feed-row.keyboard-selected .feed-row-actions {
    grid-template-rows: 1fr;
    margin-top: 0.55rem;
    opacity: 1;
}

/* The collapsing wrapper clips its content, which would cut off an open menu.
   Only while a menu is open does the row let it escape — the height animation is
   finished by then, so nothing jumps. Matches both the shared menu class and the
   one Health names its own popovers with. */
.feed-row-actions:has(.health-view-menu:not([hidden])),
.feed-row-actions:has(.health-view-menu:not([hidden])) > * {
    overflow: visible;
}

/* Nothing hovers on a touch screen, and the actions are the point of the row. */
@media (hover: none) {
    .feed-row-actions {
        grid-template-rows: 1fr;
        margin-top: 0.55rem;
        opacity: 1;
    }
}

@media (max-width: 520px) {
    .feed-row-actions {
        grid-template-rows: 1fr;
        margin-top: 0.55rem;
        opacity: 1;
    }
}

/* ==== css/spread-tutorial.css ==== */
/**
 * The spread-across-columns walkthrough.
 *
 * Same shape as inbox-tutorial.css and health-tutorial.css: the app's modal
 * chrome carries the title and the buttons, and only the reading column between
 * them is styled here. Its own sheet, so no tour's visuals drift into another's.
 *
 * The visuals in this one are diagrams rather than copies of a control — the
 * subject is a shape on the page, so stand-in columns and rows say more than a
 * screenshot of a menu would.
 */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.spread-tutorial-modal) .modal {
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.spread-tutorial-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.spread-tutorial-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

.spread-tutorial-progress {
    font-size: 0.72rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    margin: 0 0 0.4rem;
}

.spread-tutorial-step-title {
    margin: 0 0 0.7rem;
    font-size: 1.1rem;
    color: var(--text-primary);
}

.spread-tutorial-step-body p {
    margin: 0 0 0.7rem;
    color: var(--text-secondary);
    line-height: 1.55;
}

.spread-tutorial-step-body p:last-child {
    margin-bottom: 0;
}

.spread-tutorial-visual {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem;
    margin: 0 0 0.9rem;
    border: 1px dashed var(--border-secondary);
    border-radius: 0.5rem;
    background: var(--background-secondary);
}

.spread-tutorial-visual--compare,
.spread-tutorial-visual--sum {
    justify-content: center;
}

.spread-tutorial-block {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
}

.spread-tutorial-cap {
    font-size: 0.66rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

/* The stand-in category: columns of blank rows, at the proportions a real one
   has, so the before/after difference is a shape rather than a sentence. */
.spread-tutorial-grid {
    display: flex;
    gap: 0.3rem;
    padding: 0.35rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.35rem;
    background: var(--background-primary);
}

.spread-tutorial-col {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 3.1rem;
}

.spread-tutorial-row {
    height: 0.4rem;
    border-radius: 0.15rem;
    background: color-mix(in srgb, var(--accent-primary) 30%, var(--border-primary));
}

/* Every second row a little shorter: a flat stack of identical bars reads as a
   loading skeleton rather than as bookmarks. */
.spread-tutorial-row:nth-child(even) {
    width: 78%;
}

.spread-tutorial-arrow,
.spread-tutorial-op {
    color: var(--text-tertiary);
    font-size: 0.95rem;
}

.spread-tutorial-chip {
    padding: 0.15rem 0.45rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    font-size: 0.72rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.spread-tutorial-key {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.spread-tutorial-key kbd {
    padding: 0 0.3rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.25rem;
    font-family: inherit;
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

.spread-tutorial-hint {
    flex: 1 1 10rem;
    min-width: 0;
    font-size: 0.75rem;
    color: var(--text-tertiary);
}

/* The menu step: three rows of the real right-click menu, with the one this
   tour is about picked out. */
.spread-tutorial-menu {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    width: 100%;
    padding: 0.3rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.45rem;
    background: var(--background-primary);
}

.spread-tutorial-menu-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.3rem 0.45rem;
    border-radius: 0.3rem;
    font-size: 0.78rem;
    color: var(--text-tertiary);
}

.spread-tutorial-menu-row.is-current {
    background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
    color: var(--text-primary);
}

.spread-tutorial-menu-row kbd {
    margin-left: auto;
    padding: 0 0.25rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.2rem;
    font-family: inherit;
    font-size: 0.68rem;
    color: var(--text-tertiary);
}

.spread-tutorial-dots {
    display: flex;
    gap: 0.3rem;
    margin-top: 0.9rem;
}

.spread-tutorial-dot {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: var(--border-secondary);
}

.spread-tutorial-dot.is-active {
    background: var(--accent-primary);
}

/* ==== css/fresh-tutorial.css ==== */
/**
 * The Fresh walkthrough.
 *
 * Same shape as spread-tutorial.css, inbox-tutorial.css and health-tutorial.css:
 * the app's modal chrome carries the title and the buttons, and only the reading
 * column between them is styled here. Its own sheet, so no tour's visuals drift
 * into another's.
 *
 * The visuals are stand-in bookmark rows rather than diagrams, because what
 * Fresh changes is a row you already know the look of — one small count on the
 * right of it, and a collection made of the same rows.
 */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.fresh-tutorial-modal) .modal {
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.fresh-tutorial-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.fresh-tutorial-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

.fresh-tutorial-progress {
    font-size: 0.72rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    margin: 0 0 0.4rem;
}

.fresh-tutorial-step-title {
    margin: 0 0 0.7rem;
    font-size: 1.1rem;
    color: var(--text-primary);
}

.fresh-tutorial-step-body p {
    margin: 0 0 0.7rem;
    color: var(--text-secondary);
    line-height: 1.55;
}

.fresh-tutorial-step-body p:last-child {
    margin-bottom: 0;
}

.fresh-tutorial-visual {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem;
    margin: 0 0 0.9rem;
    border: 1px dashed var(--border-secondary);
    border-radius: 0.5rem;
    background: var(--background-secondary);
}

.fresh-tutorial-visual--flow {
    justify-content: center;
}

.fresh-tutorial-stack,
.fresh-tutorial-collection {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.3rem;
    padding: 0.4rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.35rem;
    background: var(--background-primary);
}

.fresh-tutorial-collection-title {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    margin-bottom: 0.15rem;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.fresh-tutorial-count {
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
}

/* A stand-in row: icon, name, and the one thing Fresh adds on the right. */
.fresh-tutorial-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.25rem 0.35rem;
    border-radius: 0.25rem;
    background: color-mix(in srgb, var(--accent-primary) 6%, transparent);
}

.fresh-tutorial-icon {
    width: 0.7rem;
    height: 0.7rem;
    flex: 0 0 auto;
    border-radius: 0.18rem;
    background: color-mix(in srgb, var(--accent-primary) 45%, transparent);
}

.fresh-tutorial-name {
    flex: 1 1 auto;
    font-size: 0.8rem;
    color: var(--text-secondary);
}

/* The count itself, drawn as the row draws it: small, quiet, on the right. */
.fresh-tutorial-badge {
    flex: 0 0 auto;
    min-width: 1.15rem;
    padding: 0.05rem 0.3rem;
    border-radius: 999px;
    background: var(--accent-primary);
    color: var(--background-primary);
    font-size: 0.68rem;
    font-weight: var(--font-weight-semibold);
    line-height: 1.4;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.fresh-tutorial-arrow {
    color: var(--text-tertiary);
    font-size: 0.95rem;
}

.fresh-tutorial-chip {
    padding: 0.15rem 0.45rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    font-size: 0.72rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* The conditional request's answer: the cheap end of the route, so it is drawn
   as the quiet one. */
.fresh-tutorial-chip--quiet {
    border-style: dashed;
    color: var(--text-tertiary);
    font-family: var(--font-mono, ui-monospace, monospace);
}

.fresh-tutorial-note {
    flex: 1 1 auto;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

.fresh-tutorial-dots {
    display: flex;
    justify-content: center;
    gap: 0.35rem;
    margin-top: 0.9rem;
}

.fresh-tutorial-dot {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 999px;
    background: var(--border-primary);
}

.fresh-tutorial-dot.is-active {
    background: var(--accent-primary);
}

/* ==== css/setting-art.css ==== */
/* ─── Setting art ───────────────────────────────────────────────────────────
   Stand-in drawings for the settings whose difference is a shape: how many
   columns, how much room between rows, how wide the margins are. Same grammar
   as the spread tour's visuals — blank bars at the proportions of the real
   thing — so config, help and the tour all draw a bookmark the same way.

   Decorative: every drawing sits beside the label that names it, so the markup
   is aria-hidden and none of this is in the accessibility tree. */

.setting-art {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    pointer-events: none;
}

.setting-art-frame {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.3rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.35rem;
    background: var(--background-primary);
}

.setting-art-col {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    width: 1.5rem;
}

.setting-art-row {
    height: 0.28rem;
    border-radius: 0.12rem;
    background: color-mix(in srgb, var(--accent-primary) 30%, var(--border-primary));
}

/* A stack of identical bars reads as a loading skeleton; the short one every
   other line reads as text. */
.setting-art-row:nth-child(even) {
    width: 76%;
}

.setting-art-more {
    align-self: flex-end;
    font-size: 0.7rem;
    line-height: 1;
    color: var(--text-tertiary);
}

/* Density is row height and row gap, and nothing else. */
.setting-art-col.is-comfortable { gap: 0.24rem; }
.setting-art-col.is-compact { gap: 0.14rem; }
.setting-art-col.is-dense { gap: 0.07rem; }
.setting-art-col.is-auto { gap: 0.14rem; }
.setting-art-col.is-dense .setting-art-row { height: 0.2rem; }
.setting-art-col.is-auto .setting-art-row:nth-child(n + 4) { height: 0.2rem; }

.setting-art-frame--density .setting-art-col {
    width: 2.6rem;
}

/* Spacing: three category blocks, moved apart. */
.setting-art-stack {
    display: flex;
    flex-direction: column;
    width: 2.8rem;
}

.setting-art-stack.is-snug { gap: 0.12rem; }
.setting-art-stack.is-balanced { gap: 0.3rem; }
.setting-art-stack.is-airy { gap: 0.5rem; }

.setting-art-band {
    height: 0.34rem;
    border-radius: 0.12rem;
    background: color-mix(in srgb, var(--accent-primary) 28%, var(--border-primary));
}

/* Margins: the page, with the edges the setting leaves empty. */
.setting-art-page {
    display: flex;
    align-items: stretch;
    width: 5.2rem;
}

.setting-art-gutter {
    flex: 0 0 auto;
    background: repeating-linear-gradient(
        45deg,
        color-mix(in srgb, var(--text-tertiary) 22%, transparent) 0 2px,
        transparent 2px 4px
    );
    border-radius: 0.12rem;
}

.setting-art-page.is-snug .setting-art-gutter { width: 0.18rem; }
.setting-art-page.is-balanced .setting-art-gutter { width: 0.42rem; }
.setting-art-page.is-airy .setting-art-gutter { width: 0.75rem; }

.setting-art-content {
    display: flex;
    flex: 1 1 auto;
    gap: 0.18rem;
    padding: 0 0.16rem;
}

.setting-art-content .setting-art-col {
    width: auto;
    flex: 1 1 0;
}

/* The dotted backdrop, drawn at its own scale rather than the grid's. */
.setting-art-dots {
    display: block;
    width: 3.2rem;
    height: 1.5rem;
    border-radius: 0.2rem;
    background: var(--background-secondary);
}

.setting-art-dots.is-on {
    background-color: var(--background-secondary);
    background-image: radial-gradient(
        color-mix(in srgb, var(--text-tertiary) 55%, transparent) 1px,
        transparent 1px
    );
    background-size: 0.42rem 0.42rem;
}

/* Type size: the only setting here whose subject is the letterform itself. */
.setting-art-type {
    display: inline-flex;
    align-items: baseline;
    justify-content: center;
    min-width: 1.9rem;
    color: var(--text-secondary);
    font-weight: var(--font-weight-semibold);
    line-height: 1;
}

/* All seven steps the picker offers, drawn at their own proportions rather
   than at three sizes standing in for seven. */
.setting-art-type.is-xs { font-size: 0.6rem; }
.setting-art-type.is-s { font-size: 0.72rem; }
.setting-art-type.is-sm { font-size: 0.85rem; }
.setting-art-type.is-m { font-size: 0.98rem; }
.setting-art-type.is-lg { font-size: 1.15rem; }
.setting-art-type.is-l { font-size: 1.32rem; }
.setting-art-type.is-xl { font-size: 1.55rem; }

/* A route rather than a shape: where a pasted link ends up, what a promote
   leaves behind. */
.setting-art-flow {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}

.setting-art-chip {
    padding: 0.1rem 0.4rem;
    border: 1px solid var(--border-secondary);
    border-radius: 999px;
    background: var(--background-secondary);
    font-size: 0.7rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.setting-art-arrow {
    font-size: 0.75rem;
    color: var(--text-tertiary);
}

/* ─── Where the drawings sit ───────────────────────────────────────────────
   On a choice card the art leads, above the title. Beside an ordinary control
   it sits on the row's right, where the reset and info buttons are, so the
   column of labels down the left is not disturbed. */
.config-choice-card .setting-art {
    margin-bottom: 0.35rem;
}

.config-field-art {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: -0.15rem 0 0.5rem auto;
    padding-right: 0.1rem;
}

/* In help, the drawing is the panel's opening line. */
.config-help-art {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    margin: 0 0 0.7rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.4rem;
    background: var(--background-secondary);
}

.config-help-art .setting-art {
    gap: 0.35rem;
}

.config-help-art-caption {
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

@media (max-width: 640px) {
    .config-field-art {
        margin-left: 0;
    }
}

/* A choice button that leads with its drawing: the letters above, the name of
   the size under them. */
.config-choice--art {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    padding: 0.35rem 0.6rem;
    line-height: 1.1;
}

.config-choice--art .setting-art {
    min-height: 1.6rem;
}

.config-choice--art .config-choice-label {
    font-size: 0.72rem;
}

/* Layout version: the same two categories, flat on the page or each on its own
   raised card — which is the difference a reader is actually choosing between. */
.setting-art-layout {
    display: flex;
    gap: 0.25rem;
}

.setting-art-card {
    padding: 0.12rem;
    border-radius: 0.1rem;
}

.setting-art-layout.is-modern .setting-art-card {
    padding: 0.18rem;
    border: 1px solid var(--border-secondary);
    border-radius: 0.28rem;
    background: var(--background-secondary);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);
}

.setting-art-layout .setting-art-col {
    width: 1.2rem;
}

/* Button bar: the page, with the bar where the setting puts it. */
.setting-art-screen {
    position: relative;
    display: block;
    width: 4.4rem;
    height: 2.5rem;
    padding: 0.22rem;
    border-radius: 0.2rem;
    background: var(--background-secondary);
}

.setting-art-screen-body {
    display: flex;
    gap: 0.16rem;
    height: 100%;
}

.setting-art-screen-body .setting-art-col {
    width: auto;
    flex: 1 1 0;
}

/* The bar really does float over the grid, so the overlap is honest — but the
   bookmarks behind it are backdrop here, not the subject, and at full strength
   they compete with the one element the drawing is about. */
.setting-art-screen-body .setting-art-row {
    background: color-mix(in srgb, var(--text-tertiary) 30%, transparent);
}

.setting-art-bar {
    position: absolute;
    border-radius: 999px;
    background: var(--accent-primary);
}

/* Horizontal bar along the bottom; the three positions differ in where along
   that edge it sits. */
.setting-art-screen.is-center-bottom .setting-art-bar,
.setting-art-screen.is-bottom-left .setting-art-bar,
.setting-art-screen.is-bottom-right .setting-art-bar {
    bottom: 0.18rem;
    height: 0.22rem;
    width: 1.5rem;
}

.setting-art-screen.is-center-bottom .setting-art-bar {
    left: 50%;
    transform: translateX(-50%);
}

.setting-art-screen.is-bottom-left .setting-art-bar { left: 0.2rem; }
.setting-art-screen.is-bottom-right .setting-art-bar { right: 0.2rem; }

/* The rails stand the same bar on its end against one edge. */
.setting-art-screen.is-side-left .setting-art-bar,
.setting-art-screen.is-side-right .setting-art-bar {
    top: 50%;
    transform: translateY(-50%);
    width: 0.22rem;
    height: 1.5rem;
}

.setting-art-screen.is-side-left .setting-art-bar { left: 0.18rem; }
.setting-art-screen.is-side-right .setting-art-bar { right: 0.18rem; }

/* Two endings from one arrow: "ask each time" does not end anywhere single. */
.setting-art-branch {
    display: inline-flex;
    flex-direction: column;
    gap: 0.15rem;
}

/* ─── The drawings help opens with ─────────────────────────────────────────
   Help is prose about a program, and half of what it describes is a shape, a
   route, a state or a key. These are the vocabulary for the other half: the
   same blank-bar grammar as above, extended so every help panel can open with
   the picture its own subject has, rather than with a paragraph that has to be
   decoded into one. Same rules as the rest of this file — markup and CSS only,
   theme tokens throughout, aria-hidden because the sentence beside each one
   already says it. */

/* Steps: the number carries the order, which is the whole claim. */
.setting-art-steps {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}

.setting-art-step {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.setting-art-step-n {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 0.95rem;
    height: 0.95rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-primary) 22%, var(--background-secondary));
    color: var(--text-secondary);
    font-size: 0.6rem;
    font-weight: var(--font-weight-semibold);
    line-height: 1;
}

.setting-art-step-label {
    font-size: 0.7rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* Keycaps, drawn the way the cheat sheet draws them so a key looks like a key
   wherever nextDash prints one. */
.setting-art-keys {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}

.setting-art-key {
    min-width: 1.05rem;
    padding: 0.08rem 0.32rem;
    border: 1px solid var(--border-primary);
    border-bottom-width: 2px;
    border-radius: 0.25rem;
    background: var(--background-primary);
    color: var(--text-secondary);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.68rem;
    line-height: 1.25;
    text-align: center;
    white-space: nowrap;
}

/* A legend, in the colours the rows themselves wear. */
.setting-art-states {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.setting-art-state {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.setting-art-state-label {
    font-size: 0.7rem;
    color: var(--text-secondary);
    white-space: nowrap;
}

.setting-art-dot {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 999px;
    background: var(--text-tertiary);
    flex: 0 0 auto;
}

.setting-art-dot.is-ok { background: var(--accent-success); }
.setting-art-dot.is-warn { background: var(--accent-warning); }
.setting-art-dot.is-bad { background: var(--accent-error); }
.setting-art-dot.is-idle { background: color-mix(in srgb, var(--accent-primary) 55%, transparent); }
/* Off is drawn as a ring rather than a pale dot: nothing is being reported,
   which is not the same as a reading that happens to be quiet. */
.setting-art-dot.is-off {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--text-tertiary);
}

/* The overlay with something typed in it. */
.setting-art-frame--field { padding: 0.22rem 0.35rem; }

.setting-art-field {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    min-width: 6.5rem;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 0.72rem;
    line-height: 1.3;
}

.setting-art-q.is-prefix {
    padding: 0 0.2rem;
    border-radius: 0.2rem;
    background: color-mix(in srgb, var(--accent-primary) 28%, transparent);
    color: var(--text-primary);
    font-weight: var(--font-weight-semibold);
}

.setting-art-q.is-token {
    padding: 0 0.2rem;
    border-radius: 0.2rem;
    background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
    color: var(--text-secondary);
}

.setting-art-q.is-text { color: var(--text-secondary); }

.setting-art-caret {
    width: 1px;
    height: 0.8rem;
    margin-left: 0.1rem;
    background: var(--accent-primary);
}

/* Counts, with the one being talked about picked out. */
.setting-art-frame--bars { align-items: flex-end; }

.setting-art-bars {
    display: flex;
    align-items: flex-end;
    gap: 0.18rem;
    height: 1.5rem;
}

.setting-art-bar-col {
    width: 0.32rem;
    border-radius: 0.1rem 0.1rem 0 0;
    background: color-mix(in srgb, var(--accent-primary) 30%, var(--border-primary));
}

.setting-art-bar-col.is-mark { background: var(--accent-primary); }
.setting-art-bar-col.is-mark.is-bad { background: var(--accent-error); }
.setting-art-bar-col.is-mark.is-warn { background: var(--accent-warning); }

/* A trend, drawn as the line the real row draws. */
.setting-art-spark {
    display: block;
    width: 3.4rem;
    height: 1.2rem;
    color: var(--accent-primary);
    overflow: visible;
}

/* How far along, and where it starts to matter. */
.setting-art-meter {
    position: relative;
    display: block;
    width: 4.2rem;
    height: 0.45rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-tertiary) 22%, transparent);
    overflow: hidden;
}

.setting-art-meter-fill {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 999px;
    background: var(--accent-primary);
}

.setting-art-meter-fill.is-warn { background: var(--accent-warning); }
.setting-art-meter-fill.is-bad { background: var(--accent-error); }

.setting-art-meter-mark {
    position: absolute;
    top: -0.1rem;
    bottom: -0.1rem;
    width: 1px;
    background: var(--text-secondary);
}

/* A day, with the hours you expect to be down shaded. */
.setting-art-day {
    display: flex;
    gap: 1px;
}

.setting-art-hour {
    width: 0.11rem;
    height: 0.85rem;
    border-radius: 0.05rem;
    background: color-mix(in srgb, var(--text-tertiary) 25%, transparent);
}

.setting-art-hour.is-window {
    background: var(--accent-warning);
}

/* Switches: some on, some off, which is what a settings tab looks like. */
.setting-art-toggles {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.setting-art-toggle {
    position: relative;
    display: block;
    width: 1.35rem;
    height: 0.55rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-tertiary) 28%, transparent);
}

.setting-art-toggle.is-on {
    background: color-mix(in srgb, var(--accent-primary) 70%, transparent);
}

.setting-art-knob {
    position: absolute;
    top: 0.08rem;
    left: 0.08rem;
    width: 0.39rem;
    height: 0.39rem;
    border-radius: 999px;
    background: var(--background-primary);
}

.setting-art-toggle.is-on .setting-art-knob {
    left: auto;
    right: 0.08rem;
}

/* Colour plates. Light and dark are halves of one theme, so they are drawn
   touching rather than as two separate chips. */
.setting-art-swatches {
    display: inline-flex;
    border: 1px solid var(--border-primary);
    border-radius: 0.3rem;
    overflow: hidden;
}

.setting-art-swatch {
    width: 1.1rem;
    height: 1.1rem;
}

.setting-art-swatch.is-light { background: #f4f4f5; }
.setting-art-swatch.is-dark { background: #1f2024; }
.setting-art-swatch.is-accent { background: var(--accent-primary); }

/* The line your data does not cross. */
.setting-art-boundary-wrap {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.setting-art-boundary {
    display: inline-flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.25rem 0.35rem;
    border: 1px dashed var(--border-primary);
    border-radius: 0.35rem;
    background: var(--background-primary);
}

.setting-art-boundary-label {
    font-size: 0.62rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.setting-art-boundary-body {
    display: inline-flex;
    gap: 0.25rem;
    flex-wrap: wrap;
}

.setting-art-blocked {
    font-size: 0.85rem;
    line-height: 1;
    color: var(--accent-error);
}

/* One row, with the parts it can carry. */
.setting-art-bmrow {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    width: 8rem;
}

.setting-art-bm-icon {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 0.12rem;
    background: color-mix(in srgb, var(--accent-primary) 45%, transparent);
    flex: 0 0 auto;
}

.setting-art-bm-name {
    flex: 1 1 auto;
    height: 0.28rem;
    border-radius: 0.12rem;
    background: color-mix(in srgb, var(--accent-primary) 30%, var(--border-primary));
}

.setting-art-bm-tag {
    width: 0.85rem;
    height: 0.35rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-primary) 18%, var(--border-primary));
    flex: 0 0 auto;
}

/* Config drawn as itself: rail, tabs, panel — the three places a sentence
   about "where the setting is" can mean. */
.setting-art-config {
    display: flex;
    gap: 0.2rem;
    width: 4.6rem;
    height: 2.2rem;
}

.setting-art-rail {
    width: 0.6rem;
    border-radius: 0.15rem;
    background: color-mix(in srgb, var(--text-tertiary) 22%, transparent);
}

.setting-art-config-main {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.2rem;
}

.setting-art-tabs {
    height: 0.3rem;
    border-radius: 0.15rem;
    background: color-mix(in srgb, var(--text-tertiary) 22%, transparent);
}

.setting-art-config-body {
    display: flex;
    flex: 1 1 auto;
    gap: 0.2rem;
    padding: 0.12rem;
    border-radius: 0.15rem;
    background: color-mix(in srgb, var(--text-tertiary) 12%, transparent);
}

.setting-art-config-body .setting-art-col { width: auto; flex: 1 1 0; }

.setting-art-rail.is-active,
.setting-art-tabs.is-active { background: var(--accent-primary); }

.setting-art-config-body.is-active {
    background: color-mix(in srgb, var(--accent-primary) 18%, transparent);
}

/* Help stacks several drawings per panel now, so the strip wraps rather than
   running off the panel on a narrow window, and each drawing keeps its caption
   under it rather than beside the next drawing's. */
.config-help-art-item {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.2rem;
}

/* ==== css/dashboard-multi-select.css ==== */
/* Multi-select on the bookmark grid.
 *
 * Deliberately built from the same tokens as .inbox-selection-bar: the two are
 * the same idea in two views, and a second visual language for "these rows are
 * ticked" would read as a different feature.
 */

.multi-select-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    margin-bottom: 0.75rem;
    padding: 0.45rem 0.65rem;
    border-radius: var(--layout-radius-sm, 8px);
    border: 1px solid color-mix(in srgb, var(--accent-primary) 40%, transparent);
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-secondary));
    /* The grid scrolls under it; the toolbar acts on a selection that may sit
     * off-screen, so it has to stay reachable. */
    position: sticky;
    top: 0;
    z-index: 5;
}

.multi-select-count {
    margin-right: 0.25rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--accent-primary);
    font-variant-numeric: tabular-nums;
}

.multi-select-btn {
    padding: 0.3rem 0.6rem;
    font-size: 0.8rem;
    font-family: inherit;
    color: var(--text-primary);
    background: var(--background-primary);
    border: 1px solid color-mix(in srgb, var(--text-primary) 18%, transparent);
    border-radius: var(--layout-radius-sm, 6px);
    cursor: pointer;
}

.multi-select-btn:hover {
    border-color: color-mix(in srgb, var(--accent-primary) 55%, transparent);
    color: var(--accent-primary);
}

.multi-select-btn:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.multi-select-btn.danger:hover {
    border-color: color-mix(in srgb, var(--accent-error) 55%, transparent);
    color: var(--accent-error);
}

/* Ticked rows.
 *
 * An inset ring rather than a background swap, so it stacks with the keyboard
 * cursor and the status accent edge instead of competing with them: a row can
 * be selected, keyboard-focused and offline at the same time.
 */
.bookmark-link.is-multi-selected {
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent-primary) 60%, transparent);
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
}

.bookmark-link.is-multi-selected.keyboard-selected {
    box-shadow: inset 0 0 0 2px var(--accent-primary);
}

body[data-layout-version="modern"] .multi-select-toolbar {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .bookmark-link.is-multi-selected {
    border-radius: var(--layout-radius-sm, 6px);
}

/* While a selection is open, a plain click clears it rather than opening the
 * link, so the pointer should not promise navigation. */
body.has-multi-selection .bookmark-link a.bookmark-open {
    cursor: default;
}

@media (prefers-reduced-motion: reduce) {
    .bookmark-link.is-multi-selected {
        transition: none;
    }
}

/* ==== css/view-explainers.css ==== */
/* ─── Explaining a view ──────────────────────────────────────────────────────

   The health and inbox views both explain themselves the same way: a sentence
   under the toolbar saying what the active filter selects, and an ℹ button that
   opens the longer "how this works" modal. Both were written for health first;
   this is that styling with the view prefix taken off, so the second view does
   not carry a near-verbatim copy that drifts from the first.

   View-specific stylesheets keep their own `.health-view-*` / `.inbox-*` aliases
   pointing at these rules, so existing markup and tests keep working.
   ────────────────────────────────────────────────────────────────────────── */

/* One sentence about the active filter, under the toolbar. Quiet enough to be
   skipped once it is known, present enough to be read the first time. */
.view-filter-note {
    margin: -0.2rem 0 0.7rem;
    padding: 0 0.35rem;
    font-size: 0.74rem;
    line-height: 1.5;
    color: var(--text-secondary);
    max-width: 70ch;
}

/* The ℹ in the toolbar. Pushed to the far end so it never sits between two
   actions and gets hit by accident. */
.view-help-btn {
    margin-left: auto;
    flex: 0 0 auto;
    width: 1.6rem;
    height: 1.6rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border-primary);
    border-radius: 0.4rem;
    background: transparent;
    color: var(--text-secondary);
    font-size: 0.78rem;
    line-height: 1;
    cursor: pointer;
}

.view-help-btn:hover,
.view-help-btn:focus-visible {
    border-color: var(--accent-primary);
    color: var(--text-primary);
}

/* The explainer modal.

   Without a max-height of its own the panel grows to whatever its sections need
   — health's six were measured at 786px in an 800px viewport, so it touched the
   bottom edge and left 14px at the top. Capping it and letting the body scroll
   keeps a clear margin above and below at any window height, and the caps are
   expressed against both vh and a fixed inset so a short window still gets its
   gap. */
.modal.view-explain-modal {
    max-height: min(78vh, calc(100vh - 6rem));
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.modal.view-explain-modal .modal-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
}

/* Config renders its own overlay above this one, where the viewport is already
   framed by the config chrome; the tighter cap keeps the same visual margin. */
body:has(#config-main) #app-modal.modal-overlay:has(.view-explain-modal) .modal {
    max-height: min(70vh, calc(100vh - 4rem));
}

/* Tighter than the 0.9rem gap the check-mode explainer uses: six sections at
   that spacing is what made health's too tall to fit. */
.view-explain-row + .view-explain-row {
    margin-top: 0.65rem;
}

.view-explain-row h4 {
    margin: 0 0 0.1rem;
    font-size: 0.88rem;
    color: var(--text-primary);
}

.view-explain-row p {
    margin: 0;
    font-size: 0.82rem;
    color: var(--text-secondary);
    line-height: 1.45;
}

/* ==== css/health-tutorial.css ==== */
/**
 * The one-time Health tutorial modal.
 *
 * Reuses the app's modal chrome (title, confirm/cancel buttons) entirely —
 * only the body content between them is custom, sized narrow like the
 * whats-new modal (a single reading column, not a wide two-pane surface).
 */
body:has(#dashboard-layout) #app-modal.modal-overlay:has(.health-tutorial-modal) .modal {
    transform: translateY(10px) scale(0.98);
    transition: transform 0.15s ease-in, opacity 0.15s ease-in;
}

body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.health-tutorial-modal) .modal {
    transform: translateY(0) scale(1);
    transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.22s ease-out;
}

body.no-animations:has(#dashboard-layout) #app-modal.modal-overlay:has(.health-tutorial-modal) .modal {
    transform: none !important;
    transition: opacity 0.15s ease !important;
}

.health-tutorial-progress {
    font-size: 0.72rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    margin: 0 0 0.4rem;
}

.health-tutorial-step-title {
    margin: 0 0 0.7rem;
    font-size: 1.1rem;
    color: var(--text-primary);
}

.health-tutorial-step-body p {
    margin: 0 0 0.7rem;
    color: var(--text-secondary);
    line-height: 1.55;
}

.health-tutorial-step-body p:last-child {
    margin-bottom: 0;
}

.health-tutorial-closing {
    color: var(--text-primary) !important;
    font-style: italic;
}

/* The small "here is the actual control" preview above each step's prose. */
.health-tutorial-visual {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.6rem 0.75rem;
    margin: 0 0 0.9rem;
    border: 1px dashed var(--border-secondary);
    border-radius: 0.5rem;
    background: var(--background-secondary);
}

.health-tutorial-visual-url {
    font-family: var(--font-mono, monospace);
    font-size: 0.78rem;
    color: var(--text-secondary);
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.health-tutorial-visual-modes {
    display: inline-flex;
    gap: 0.3rem;
    flex: 0 0 auto;
}

.health-tutorial-visual code {
    font-family: var(--font-mono, monospace);
    font-size: 0.8rem;
    padding: 0.15rem 0.45rem;
    border-radius: 0.35rem;
    background: var(--background-primary);
    border: 1px solid var(--border-secondary);
    color: var(--text-primary);
}

.health-tutorial-visual-hint {
    font-size: 0.72rem;
    color: var(--text-tertiary);
}

.health-tutorial-visual--window {
    justify-content: space-between;
}

.health-tutorial-visual--services {
    gap: 0.35rem;
}

.health-tutorial-visual-chip {
    font-size: 0.72rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--border-secondary);
    color: var(--text-secondary);
    background: var(--background-primary);
}

/* Mirrors .health-drift-badge / .health-cert-badge exactly, so a reader who
   later sees the real badge on a row recognises it. */
.health-tutorial-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.05rem 0.4rem;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-size: 0.7rem;
    white-space: nowrap;
    opacity: 0.9;
    color: var(--accent-warning, #b45309);
}

.health-tutorial-badge--moved,
.health-tutorial-badge--retitled,
.health-tutorial-badge--changed {
    color: var(--accent-warning, #b45309);
}

.health-tutorial-dots {
    display: flex;
    justify-content: center;
    gap: 0.4rem;
    margin-top: 1.2rem;
}

.health-tutorial-dot {
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 999px;
    background: var(--border-secondary);
    transition: background-color 0.15s ease, transform 0.15s ease;
}

.health-tutorial-dot.is-active {
    background: var(--accent-primary);
    transform: scale(1.3);
}

@media (prefers-reduced-motion: reduce) {
    body:has(#dashboard-layout) #app-modal.modal-overlay:has(.health-tutorial-modal) .modal,
    body:has(#dashboard-layout) #app-modal.modal-overlay.show:has(.health-tutorial-modal) .modal {
        transform: none !important;
        transition: opacity 0.15s ease !important;
    }

    .health-tutorial-dot {
        transition: none;
    }
}

/* ==== css/health-focus.css ==== */
/*
 * Focus mode: one health issue at a time, over the list it came from.
 *
 * Styled as an overlay rather than a separate page on purpose — the list stays
 * visible behind it, so working through a queue never feels like leaving the
 * view. The card is deliberately narrow: the whole point is that one decision
 * is on screen and nothing else is competing for the click.
 */

.health-focus-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    background: var(--background-modal, rgba(0, 0, 0, 0.6));
    animation: health-focus-fade 0.14s ease-out;
}

.health-focus-card {
    width: min(34rem, 100%);
    max-height: 85vh;
    overflow-y: auto;
    padding: 1.5rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.75rem;
    background: var(--background-secondary);
    color: var(--text-primary);
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.35);
    animation: health-focus-rise 0.16s ease-out;
}

/* While an action is in flight the card stays put and stops taking clicks,
   rather than swapping in a spinner that would move everything underneath the
   pointer mid-decision. */
.health-focus-overlay.is-busy .health-focus-card {
    opacity: 0.6;
    pointer-events: none;
}

.health-focus-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.75rem;
}

.health-focus-progress {
    font-size: 0.78rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.health-focus-close {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-size: 1.4rem;
    line-height: 1;
    padding: 0 0.25rem;
    cursor: pointer;
    border-radius: 0.3rem;
}

.health-focus-close:hover {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--text-primary) 8%, transparent);
}

.health-focus-title {
    margin: 0 0 0.25rem;
    font-size: 1.15rem;
    line-height: 1.3;
    /* Long bookmark names break rather than widening the card past the
       measure the rest of the layout is built on. */
    overflow-wrap: anywhere;
}

.health-focus-url {
    margin: 0 0 0.75rem;
    font-size: 0.82rem;
    color: var(--text-secondary);
    overflow-wrap: anywhere;
}

.health-focus-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-bottom: 0.75rem;
}

/* Collapses to nothing when the row has no badges, so the gap above the
   reasons does not depend on whether any were rendered. */
.health-focus-badges:empty {
    display: none;
    margin-bottom: 0;
}

.health-focus-reasons {
    margin: 0 0 1.1rem;
    padding-left: 1.1rem;
    font-size: 0.86rem;
    color: var(--text-secondary);
    line-height: 1.5;
}

.health-focus-reasons li + li {
    margin-top: 0.2rem;
}

.health-focus-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.9rem;
}

/* The key hint rides inside its button, the same pairing the row actions use,
   so the shortcut is learned from the control rather than from a legend. */
.health-focus-actions kbd {
    margin-left: 0.4rem;
    padding: 0.05rem 0.3rem;
    border: 1px solid var(--border-secondary, var(--border-primary));
    border-radius: 0.25rem;
    background: color-mix(in srgb, var(--text-primary) 6%, transparent);
    font-family: inherit;
    font-size: 0.68rem;
    opacity: 0.8;
}

.health-focus-legend {
    margin: 0;
    font-size: 0.74rem;
    color: var(--text-tertiary, var(--text-secondary));
}

@keyframes health-focus-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes health-focus-rise {
    from { opacity: 0; transform: translateY(8px) scale(0.99); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .health-focus-overlay,
    .health-focus-card {
        animation: none;
    }
}

/* On a phone the card is the screen: full width, and the actions stack so no
   button ends up too narrow to hit. */
@media (max-width: 30rem) {
    .health-focus-overlay {
        padding: 0.75rem;
    }

    .health-focus-card {
        width: 100%;
        padding: 1.1rem;
    }

    .health-focus-actions .config-btn {
        flex: 1 1 100%;
    }
}

/* The toolbar entry point. Sized and coloured like the other toolbar buttons;
   only the key hint is extra. */
.health-view-focus-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--border-primary);
    border-radius: 0.4rem;
    background: var(--background-primary);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.78rem;
    cursor: pointer;
}

.health-view-focus-btn:hover {
    color: var(--text-primary);
    border-color: var(--border-secondary, var(--border-primary));
}

.health-view-focus-btn kbd {
    margin-left: 0.3rem;
    padding: 0.02rem 0.28rem;
    border: 1px solid var(--border-secondary, var(--border-primary));
    border-radius: 0.25rem;
    font-family: inherit;
    font-size: 0.66rem;
    opacity: 0.75;
}

/* The end of a review session. Same card, no row on it — what is left to show
   is a count and a decision about tomorrow. */
.health-focus-card--done {
    text-align: center;
}

.health-focus-done-count {
    margin: 0.75rem 0 0.25rem;
    font-size: 1.05rem;
    color: var(--text-primary);
}

.health-focus-done-rest {
    margin: 0 0 1.25rem;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.health-focus-card--done .health-focus-actions {
    justify-content: center;
}

.health-focus-done-primary {
    border-color: var(--accent-primary);
    color: var(--accent-primary);
}

/* ==== css/config-setting-promo.css ==== */
/* One-time config setting highlight popovers (see config-setting-promo.js) */

.config-setting-promo-anchor-highlight {
    position: relative;
    z-index: 1;
    border-radius: 10px;
    outline: 2px solid color-mix(in srgb, var(--accent-primary, #4a90d9) 55%, transparent);
    outline-offset: 4px;
    animation: config-setting-promo-anchor-pulse 2.4s ease-in-out infinite;
}

@keyframes config-setting-promo-anchor-pulse {
    0%, 100% { outline-color: color-mix(in srgb, var(--accent-primary, #4a90d9) 40%, transparent); }
    50% { outline-color: color-mix(in srgb, var(--accent-primary, #4a90d9) 78%, transparent); }
}

.config-setting-promo {
    position: fixed;
    z-index: 1200;
    max-width: min(300px, calc(100vw - 24px));
    pointer-events: auto;
    opacity: 0;
    transform: translateY(8px) scale(0.98);
    transition: opacity 0.22s ease, transform 0.22s ease;
}

.config-setting-promo.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
}

@keyframes config-setting-promo-float {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(-3px) scale(1); }
}

.config-setting-promo-inner {
    position: relative;
    background: var(--background-secondary, var(--card-bg, #1e1e1e));
    border: 1px solid var(--border-primary, var(--border-color, rgba(128, 128, 128, 0.35)));
    border-radius: 0.75rem;
    padding: 0.85rem 0.95rem 0.9rem;
    box-shadow:
        0 10px 28px rgba(0, 0, 0, 0.22),
        0 0 0 1px color-mix(in srgb, var(--accent-primary, #4a90d9) 18%, transparent);
}

.config-setting-promo-badge {
    display: inline-block;
    margin-bottom: 0.35rem;
    padding: 0.12rem 0.45rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--accent-primary, #4a90d9);
    background: color-mix(in srgb, var(--accent-primary, #4a90d9) 16%, transparent);
}

.config-setting-promo-title {
    margin: 0 0 0.35rem;
    font-size: calc(var(--font-size-text, 14px) * 1.05);
    font-weight: 600;
    color: var(--text-primary, inherit);
    line-height: 1.3;
}

.config-setting-promo-body {
    margin: 0 0 0.75rem;
    font-size: calc(var(--font-size-text, 14px) * 0.94);
    color: var(--text-secondary, var(--text-muted, #aaa));
    line-height: 1.45;
}

.config-setting-promo-dismiss {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem 0.75rem;
    border: none;
    border-radius: 0.45rem;
    font: inherit;
    font-size: calc(var(--font-size-text, 14px) * 0.94);
    font-weight: 600;
    cursor: pointer;
    color: var(--background-primary, #fff);
    background: var(--accent-primary, #4a90d9);
    transition: filter 0.12s ease, transform 0.12s ease;
}

.config-setting-promo-dismiss:hover {
    filter: brightness(1.08);
}

.config-setting-promo-dismiss:focus-visible {
    outline: 2px solid var(--accent-primary, #4a90d9);
    outline-offset: 2px;
}

.config-setting-promo-arrow {
    position: absolute;
    width: 10px;
    height: 10px;
    background: var(--background-secondary, var(--card-bg, #1e1e1e));
    border: 1px solid var(--border-primary, var(--border-color, rgba(128, 128, 128, 0.35)));
    transform: rotate(45deg);
    box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.08);
}

/* Below the control (default) */
.config-setting-promo.is-below .config-setting-promo-arrow {
    top: -5px;
    left: var(--promo-arrow-left, 50%);
    margin-left: -5px;
    border-right: none;
    border-bottom: none;
}

/* Above the control when there is no room below */
.config-setting-promo.is-above .config-setting-promo-arrow {
    bottom: -5px;
    left: var(--promo-arrow-left, 50%);
    margin-left: -5px;
    border-left: none;
    border-top: none;
}

/* Beside the control (optional placement) */
.config-setting-promo.is-right .config-setting-promo-arrow,
.config-setting-promo.is-left .config-setting-promo-arrow {
    top: 50%;
    margin-top: -5px;
    margin-left: 0;
}

.config-setting-promo.is-right .config-setting-promo-arrow {
    left: -5px;
    border-right: none;
    border-top: none;
}

.config-setting-promo.is-left .config-setting-promo-arrow {
    right: -5px;
    border-left: none;
    border-bottom: none;
}

@media (max-width: 720px) {
    .config-setting-promo {
        display: none !important;
    }

    .config-setting-promo-anchor-highlight {
        animation: none;
        outline-width: 1px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .config-setting-promo,
    .config-setting-promo.is-visible,
    .config-setting-promo-anchor-highlight {
        animation: none !important;
        transition: none !important;
    }

    .config-setting-promo {
        opacity: 1;
        transform: none;
    }
}

body.no-animations .config-setting-promo,
body.no-animations .config-setting-promo.is-visible,
body.no-animations .config-setting-promo-anchor-highlight {
    animation: none !important;
    transition: none !important;
}

body.no-animations .config-setting-promo {
    opacity: 1;
    transform: none;
}

/* ==== css/colors.css ==== */
/* Colors editor — embedded in Config (#colors tab) */

.theme-colors-editor {
    display: flex;
    flex-direction: column;
    gap: var(--config-tab-gap, 0.85rem);
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.theme-colors-editor--readonly .theme-colors-actions button:not(.colors-readonly-allowed),
.theme-colors-editor--readonly #add-custom-theme-btn,
.theme-colors-editor--readonly .custom-theme-move-btn,
.theme-colors-editor--readonly .custom-theme-list-item .btn-danger,
.theme-colors-editor--readonly .custom-theme-list-item input {
    opacity: 0.55;
    pointer-events: none;
}

.colors-mobile-readonly-banner {
    margin: 0;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-secondary);
    font-size: var(--font-size-text);
    line-height: 1.45;
}

.colors-contrast-hint {
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-left: 3px solid var(--accent-warning);
    background: color-mix(in srgb, var(--accent-warning) 12%, transparent);
    color: var(--text-secondary);
    font-size: var(--font-size-text);
}

.color-text-input.color-input-invalid,
.color-text-input-full.color-input-invalid {
    border-color: var(--accent-error);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-error) 35%, transparent);
}

.colors-palette-live-preview {
    margin-bottom: 1.25rem;
    position: static;
    top: auto;
}

.custom-theme-list-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.custom-theme-reorder-btns {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.custom-theme-move-btn {
    min-width: 2rem;
    padding: 0.15rem 0.35rem;
    line-height: 1;
}

.theme-colors-intro .simple-tab-intro {
    display: block;
    line-height: 1.5;
}

.theme-colors-intro .help-text,
.theme-colors-intro p {
    margin: 0 0 0.5rem;
    color: var(--text-secondary);
    font-size: var(--font-size-text);
    line-height: 1.5;
}

.theme-colors-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--border-primary);
}

.theme-colors-toolbar.config-tab-toolbar--in-surface {
    border: none;
    border-radius: 0;
    box-shadow: none;
    margin: 0;
    width: 100%;
    max-width: 100%;
    padding-bottom: var(--config-toolbar-padding-block, 0.5rem);
    background: var(--config-surface-toolbar, color-mix(in srgb, var(--background-primary) 35%, transparent));
}

/* Theme tab — fused surface (B10/C11) */
.theme-colors-tab-surface .theme-colors-body {
    display: flex;
    flex-direction: column;
    gap: 0;
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

.theme-colors-tab-surface .colors-tab-panel {
    padding: 0;
    border: none;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
}

.theme-colors-tab-surface .colors-tab-panel .config-section {
    padding: 0.9rem 1rem;
    border: none;
}

.theme-colors-tab-surface .colors-panel-hint,
.theme-colors-tab-surface .colors-tab-panel > .config-section > .help-text {
    margin: 0 0 0.75rem;
}

.theme-colors-tab-surface .page-selector-wrapper {
    margin: 0 0 0.75rem;
    padding: 0;
    border: none;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

.theme-colors-tab-surface .colors-grid {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-top: 0.75rem;
    border: 1px solid var(--border-primary);
    background: var(--config-surface-list, transparent);
}

.theme-colors-tab-surface .color-group {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--border-primary);
}

.theme-colors-tab-surface .color-group:last-child {
    border-bottom: none;
}

.theme-colors-tab-surface .color-group h3 {
    margin: 0 0 0.5rem;
}

.theme-colors-tab-surface .color-item {
    margin-bottom: 0;
    padding: 0.45rem 0;
    min-height: 2.25rem;
    box-sizing: border-box;
    border-bottom: 1px solid var(--border-primary);
    background: transparent;
    transition: background-color 0.12s ease;
}

.theme-colors-tab-surface .color-group .color-item:last-child {
    border-bottom: none;
}

.theme-colors-tab-surface .color-item:hover {
    background: var(--config-row-hover, color-mix(in srgb, var(--accent-primary) 8%, transparent));
}

.theme-colors-tab-surface #custom-themes-list.categories-list {
    border: 1px solid var(--border-primary);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}

.theme-colors-tab-surface .custom-themes-main-grid {
    gap: 0;
    margin-top: 1rem;
    border-top: 1px solid var(--border-primary);
}

.theme-colors-tab-surface .custom-themes-list-section {
    padding: 0.9rem 1rem 1rem 0;
    border-right: 1px solid var(--border-primary);
}

.theme-colors-tab-surface .custom-theme-colors-section {
    border-left: none;
    padding: 0.9rem 0 1rem 1rem;
    margin-top: 0;
}

.theme-colors-tab-surface .theme-preview-card {
    border-radius: 0;
    box-shadow: none;
    border: 1px solid var(--border-primary);
    margin-bottom: 1rem;
}

.theme-colors-tab-surface .theme-preview-label {
    background: var(--config-surface-toolbar, color-mix(in srgb, var(--background-primary) 25%, transparent));
}

@media (max-width: 1024px) {
    .theme-colors-tab-surface .custom-themes-main-grid {
        border-top: 1px solid var(--border-primary);
    }

    .theme-colors-tab-surface .custom-themes-list-section {
        padding: 0.9rem 1rem 0;
        border-right: none;
        border-bottom: 1px solid var(--border-primary);
    }

    .theme-colors-tab-surface .custom-theme-colors-section {
        padding: 0.9rem 1rem 1rem;
    }
}

.theme-colors-toolbar {
    justify-content: space-between;
}

.theme-colors-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-left: auto;
}

.theme-colors-info-btn {
    flex-shrink: 0;
    align-self: center;
}

.colors-subtabs-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.theme-colors-section-heading {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-bottom: 1rem;
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.05em;
    color: var(--text-tertiary);
    text-transform: lowercase;
}

.theme-colors-section-heading::before {
    content: '// ';
}

.colors-panel-hint {
    margin: 0 0 1rem;
}

/* colors unsaved badge: config-unsaved-state.css (.unsaved-badge) */

.colors-subtabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0;
    padding: 0;
    border: 1px solid var(--border-primary);
    border-radius: 4px;
    overflow: visible;
    background: transparent;
}

.colors-tab-button {
    appearance: none;
    border: none;
    border-radius: 0;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 0.85rem;
    font-weight: inherit;
    padding: 0.35rem 0.75rem;
    cursor: pointer;
    text-transform: lowercase;
    transition: background 0.15s ease, color 0.15s ease;
    position: relative;
}

.colors-tab-button + .colors-tab-button {
    border-left: 1px solid var(--border-primary);
}

.colors-tab-button:hover {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
}

.colors-tab-button.active {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--accent-primary) 22%, transparent);
    font-weight: var(--font-weight-bold, 600);
}

.colors-tab-button:focus-visible {
    outline: 2px solid var(--accent-primary);
    outline-offset: 2px;
}

.colors-tab-panel[hidden] {
    display: none !important;
}

.colors-grid {
    display: flex;
    flex-direction: column;
    gap: 3rem;
    margin-top: 1rem;
}

.color-group {
    border: none;
    padding: 0;
}

.color-group h3 {
    margin-top: 0;
    margin-bottom: 1rem;
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.05em;
    color: var(--text-tertiary);
    text-transform: lowercase;
    border: none;
    padding: 0;
}

.color-group h3::before {
    content: '// ';
}

.color-item {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    gap: 1rem;
}

.color-item:last-child {
    margin-bottom: 0;
}

.color-item label {
    font-size: var(--font-size-text);
    color: var(--text-secondary);
    font-weight: var(--font-weight-semibold);
    min-width: var(--config-label-width, 10rem);
    margin: 0;
}

.color-input-wrapper {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex: 1;
}

.color-input-wrapper input[type="color"] {
    width: 40px;
    height: 28px;
    border: none;
    border-bottom: 1px solid var(--border-primary);
    border-radius: 0;
    cursor: pointer;
    background: transparent;
    padding: 0;
    transition: border-color 0.2s ease;
}

.color-input-wrapper input[type="color"]:hover {
    border-bottom-color: var(--text-secondary);
}

.color-input-wrapper input[type="color"]:focus {
    outline: none;
    border-bottom-color: var(--text-primary);
}

.color-text-input {
    flex: 1;
    min-width: 120px;
    padding: 0.375rem 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-text);
    transition: border-color 0.3s ease;
}

.color-text-input-full {
    width: 100%;
    max-width: 300px;
    padding: 0.375rem 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: var(--font-size-text);
    transition: border-color 0.3s ease;
}

.color-text-input:focus,
.color-text-input-full:focus {
    outline: none;
    border-color: var(--text-secondary);
}

.color-text-input:hover,
.color-text-input-full:hover {
    border-color: var(--text-secondary);
}

/* Responsive adjustments for colors page */
@media (max-width: 768px) {
    .theme-colors-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .theme-colors-actions,
    .colors-subtabs {
        width: 100%;
    }

    .colors-subtabs {
        overflow-x: auto;
        flex-wrap: nowrap;
        padding-bottom: 0.25rem;
    }

    .color-item {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
    }

    .color-item label {
        min-width: auto;
    }

    .color-input-wrapper {
        width: 100%;
    }

    .color-text-input {
        max-width: 100%;
    }

    .color-input-wrapper input[type="color"] {
        width: 36px;
        height: 24px;
    }
}

/* Custom Themes Section */
.custom-themes-main-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    margin-top: 2rem;
}

.custom-themes-list-section h3 {
    margin-bottom: 1rem;
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-bold);
    letter-spacing: 0.05em;
    color: var(--text-tertiary);
    text-transform: lowercase;
}

.custom-themes-list-section h3::before {
    content: '// ';
}

#custom-themes-list {
    margin-bottom: 1rem;
}

.custom-themes-list-section .category-item {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.75rem;
    align-items: center;
}

.custom-themes-list-section .category-item input {
    width: 100%;
}

.custom-themes-list-section .btn-danger {
    min-width: 88px;
    padding: 0.375rem 0.625rem;
}

#add-custom-theme-btn {
    margin-top: 0.25rem;
}

.custom-theme-colors-section {
    border-left: 1px solid var(--border-primary);
    padding-left: 2rem;
}

.custom-theme-colors-section .colors-grid {
    margin-top: 0;
}

/* Theme preview card */
.theme-preview-card {
    position: sticky;
    top: 6rem;
    margin-bottom: 2rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    font-size: var(--font-size-controls);
    user-select: none;
    pointer-events: none;
}

.theme-preview-label {
    padding: 0.35rem 0.75rem;
    font-size: 0.72em;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-primary);
    background: var(--background-secondary);
}

.theme-preview-body {
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.theme-preview-category {
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    padding: 0.5rem 0.65rem;
}

.theme-preview-category-title {
    display: block;
    font-size: 0.78em;
    font-weight: var(--font-weight-bold);
    color: var(--text-tertiary);
    margin-bottom: 0.4rem;
}

.theme-preview-bookmark {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.25rem 0;
    border-bottom: 1px solid var(--border-primary);
}

.theme-preview-bookmark:last-child {
    border-bottom: none;
}

.theme-preview-bm-name {
    color: var(--text-primary);
    font-size: 0.9em;
}

.theme-preview-bm-shortcut {
    color: var(--text-tertiary);
    font-size: 0.75em;
    opacity: 0.65;
}

.theme-preview-controls {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    align-items: center;
}

.theme-preview-input {
    flex: 1;
    min-width: 0;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--border-primary);
    background: var(--background-primary);
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.85em;
}

.theme-preview-btn {
    padding: 0.25rem 0.6rem;
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.85em;
    cursor: default;
}

.theme-preview-btn-success {
    border-color: var(--accent-success);
    color: var(--accent-success);
}

.theme-preview-btn-danger {
    border-color: var(--accent-error);
    color: var(--accent-error);
}

.theme-preview-badges {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.theme-preview-badge {
    padding: 0.15rem 0.5rem;
    font-size: 0.78em;
    border: 1px solid currentColor;
}

.theme-preview-badge-success { color: var(--accent-success); }
.theme-preview-badge-warning { color: var(--accent-warning); }
.theme-preview-badge-error   { color: var(--accent-error); }

@media (max-width: 1024px) {
    .custom-themes-main-grid {
        grid-template-columns: 1fr;
        gap: 2rem;
    }

    .custom-theme-colors-section {
        border-left: none;
        border-top: 1px solid var(--border-primary);
        padding-left: 0;
        padding-top: 1.5rem;
    }

    .theme-preview-card {
        position: static;
    }
}
/* ==== css/enhanced-features.css ==== */
/* Enhanced Features CSS */

/* The bare `kbd` rule below is the one that actually applies: this file
   loads after dashboard-enhancements.css, which declares kbd too, so this
   copy wins on order. It is kept here rather than folded into that file to
   avoid changing how every keyboard hint renders. */
kbd {
    background: var(--background-primary);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
    padding: 4px 8px;
    font-family: monospace;
    font-size: 12px;
    color: var(--text-primary);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    white-space: nowrap;
}

/* ===== Empty States ===== */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    padding: 3rem 0;
    text-align: left;
    color: var(--text-secondary);
    max-width: 40ch;
}

.empty-state-label {
    font-size: var(--font-size-category);
    font-weight: var(--font-weight-bold);
    color: var(--text-tertiary);
    margin-bottom: 0.75rem;
    letter-spacing: 0.04em;
}

.empty-state-text {
    font-size: var(--font-size-text);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    margin-bottom: 0.5rem;
}

.empty-state-action {
    margin-top: 1.5rem;
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.empty-state-actions {
    margin-top: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.empty-state-hint {
    margin: 0.85rem 0 0;
    font-size: calc(var(--font-size-controls) * 0.92);
    color: var(--text-tertiary, var(--text-secondary));
    line-height: 1.45;
    max-width: 22rem;
}

.empty-state-action-btn--primary {
    border-color: color-mix(in srgb, var(--accent-primary, var(--text-primary)) 65%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary, var(--text-primary)) 14%, var(--background-primary));
    font-weight: var(--font-weight-semibold);
}

.empty-state-action-btn--primary:hover {
    background: color-mix(in srgb, var(--accent-primary, var(--text-primary)) 22%, var(--background-primary));
}

.empty-state-action-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    background: none;
    border: none;
    padding: 0.2rem 0;
    font-size: var(--font-size-controls);
    color: var(--text-secondary);
    cursor: pointer;
    text-align: left;
    transition: color 0.12s ease;
}

.empty-state-action-btn:hover {
    color: var(--text-primary);
}

.empty-state-action-btn kbd {
    font-family: var(--font-family-main);
    font-size: 0.9em;
    color: var(--text-primary);
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
    border-radius: 3px;
    padding: 0 0.3em;
    transition: background 0.12s ease;
}

.empty-state-action-btn:hover kbd {
    background: color-mix(in srgb, var(--accent-primary) 15%, var(--background-secondary));
    border-color: var(--accent-primary);
}

/* Secondary text links under the fresh empty state (add modal, config, import).
   Styled locally because the global .btn styles are config-only and don't load
   on the dashboard — bare <a> would otherwise render as raw browser links. */
.empty-state-links {
    margin-top: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.55rem;
}

.empty-state-link {
    display: inline-flex;
    align-items: center;
    background: none;
    border: none;
    padding: 0;
    font-family: inherit;
    font-size: calc(var(--font-size-controls) * 0.92);
    color: var(--text-secondary);
    text-decoration: none;
    border-bottom: 1px dotted color-mix(in srgb, var(--text-secondary) 55%, transparent);
    cursor: pointer;
    transition: color 0.12s ease, border-color 0.12s ease;
}

.empty-state-link:hover {
    color: var(--text-primary);
    border-bottom-color: var(--accent-primary, var(--text-primary));
}

/* ===== Lazy Load Placeholders ===== */
.icon-placeholder {
    background: linear-gradient(90deg, var(--background-modal) 25%, var(--background-primary) 50%, var(--background-modal) 75%);
    background-size: 200% 100%;
    animation: loading 1.5s infinite;
    border-radius: 4px;
    width: 1.15em;
    height: 1.15em;
    display: inline-block;
}

@keyframes loading {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ==== css/mobile-experience.css ==== */
/* ── Mobile / compact layout overrides ── */

.mobile-experience-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
    margin: 0 0 0.75rem;
    padding: 0.65rem 0.85rem;
    border: 1px solid color-mix(in srgb, var(--accent-primary) 45%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary));
    border-radius: 0.35rem;
    font-size: var(--font-size-controls);
    line-height: 1.45;
    color: var(--text-secondary);
}

.mobile-experience-banner[hidden] {
    display: none !important;
}

.mobile-experience-banner-text {
    margin: 0;
    flex: 1 1 14rem;
}

.mobile-experience-banner-text a {
    color: var(--accent-primary);
    font-weight: var(--font-weight-semibold);
}

.mobile-experience-banner-actions {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.35rem;
}

.mobile-experience-banner-dismiss {
    border: 1px solid var(--border-primary);
    background: var(--background-secondary);
    color: var(--text-secondary);
    width: 2rem;
    height: 2rem;
    border-radius: 0.25rem;
    cursor: pointer;
    font-size: 1.25rem;
    line-height: 1;
    padding: 0;
}

.mobile-experience-banner-dismiss:hover {
    color: var(--text-primary);
}

/* ── Dashboard: footer — search + add bookmark on mobile ── */
body[data-mobile-layout="true"] #finders-button,
body[data-mobile-layout="true"] #commands-button,
body[data-mobile-layout="true"] #recent-bookmarks-button,
body[data-mobile-layout="true"] #help-button,
body[data-mobile-layout="true"] #whats-new-btn,
body[data-mobile-layout="true"] .btn-group-secondary {
    display: none !important;
}

body[data-mobile-layout="true"] #quick-add-toolbar-btn {
    display: flex !important;
    order: -1;
    flex: 1 1 auto;
    min-height: 44px;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

body[data-mobile-layout="true"] .button-container {
    justify-content: center;
    width: calc(100% - 2rem);
    flex-wrap: wrap;
    row-gap: 0.35rem;
}

body[data-mobile-layout="true"] .btn-group-primary {
    justify-content: center;
    width: 100%;
    gap: 0.5rem;
}

body[data-mobile-layout="true"] #search-button {
    flex: 1 1 auto;
    max-width: none;
    min-height: 44px;
}

/* Dashboard: single column on phone — ignore columnsPerRow / packed layout */
@media (max-width: 767px) {
    body[data-dashboard-stack-categories="true"] .dashboard-grid,
    .dashboard-grid.columns-2,
    .dashboard-grid.columns-3,
    .dashboard-grid.columns-4,
    .dashboard-grid.columns-5,
    .dashboard-grid.columns-6 {
        display: grid !important;
        grid-template-columns: 1fr !important;
    }

    body[data-dashboard-stack-categories="true"] .dashboard-grid.packed-columns,
    .dashboard-grid.packed-columns {
        display: flex !important;
        flex-direction: column !important;
        flex-wrap: nowrap !important;
    }

    body[data-dashboard-stack-categories="true"] .dashboard-grid.packed-columns .dashboard-column,
    .dashboard-grid.packed-columns .dashboard-column {
        flex: 1 1 100% !important;
        max-width: 100% !important;
        width: 100% !important;
    }
}

/* Search mode tabs visible on mobile (override search.css ≤479px hide) */
body[data-mobile-layout="true"] .search-mode-tabs {
    display: flex !important;
}

body[data-mobile-layout="true"] .search-mode-tab {
    min-height: 44px;
    flex: 1 1 0;
}

/* Header simplification */
body[data-mobile-layout="true"] .health-link,
body[data-mobile-layout="true"] #page-navigation,
body[data-mobile-layout="true"] #page-nav-inbox-host,
body[data-mobile-layout="true"] #dashboard-tag-cloud-wrap,
body[data-mobile-layout="true"] #status-loading-indicator {
    display: none !important;
}

/* Header: Pages + config only — touch-friendly targets */
body[data-mobile-layout="true"] .header-actions {
    gap: 0.5rem;
    flex-shrink: 0;
}

body[data-mobile-layout="true"] #page-overview-header-btn,
body[data-mobile-layout="true"] .pages-link--icon .pages-link-anchor {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
    padding: 0.55rem;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

body[data-mobile-layout="true"] #page-overview-header-btn:active,
body[data-mobile-layout="true"] .pages-link--icon .pages-link-anchor:active {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary));
}

body[data-mobile-layout="true"] .config-link a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    min-width: 44px;
    /* Symmetric now the label is an icon; the wider side padding was there to
       sit around the word "config". */
    padding: 0.55rem;
    border: 1px solid color-mix(in srgb, var(--text-secondary) 35%, transparent);
    border-radius: var(--header-chip-radius, var(--layout-radius-pill, 999px));
    background: color-mix(in srgb, var(--background-secondary) 55%, transparent);
    text-transform: capitalize;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

/* The icon variant's negative pull is for sitting beside the health icon, which
   mobile hides — without this the chip would overlap the pages button. */
body[data-mobile-layout="true"] .config-link--icon {
    margin-left: 0;
}

body[data-mobile-layout="true"] .config-link a:active,
body[data-mobile-layout="true"] #page-overview-header-btn:active,
body[data-mobile-layout="true"] .pages-link--icon .pages-link-anchor:active {
    background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
    color: var(--text-primary);
    border-color: var(--text-primary);
}

/* Link preview cards — no hover on touch */
body[data-mobile-hide-previews="true"] .link-preview-card,
body[data-mobile-hide-previews="true"] .bookmark-preview-popup {
    display: none !important;
}

/* ── Config: tabs & general panels (phone only — tablets keep full config) ── */
body[data-phone-layout="true"] .tab-button:not([data-tab="general"]):not([data-tab="help"]):not([data-tab="colors"]),
body[data-phone-layout="true"] .config-keyboard-chip {
    display: none !important;
}

body[data-phone-layout="true"] [data-general-panel][data-mobile-panel-hidden="true"],
body[data-phone-layout="true"] #general-layer-toolbar {
    display: none !important;
}

/* Config General — touch-friendly theme & language selects */
body[data-mobile-layout="true"] .form-group--theme-select .custom-select-trigger,
body[data-mobile-layout="true"] .form-group:has(#language-select) .custom-select-trigger {
    min-height: 44px;
    padding: 0.65rem 0.85rem;
    touch-action: manipulation;
}

body[data-mobile-layout="true"] .custom-select-option {
    min-height: 44px;
    padding: 0.65rem 0.85rem;
    display: flex;
    align-items: center;
}

body[data-mobile-layout="true"] .form-group--theme-select label,
body[data-mobile-layout="true"] .form-group:has(#language-select) label {
    font-weight: var(--font-weight-semibold);
}

body[data-mobile-layout="true"] .general-keyboard-link-row {
    display: none !important;
}

/* Search-flow hint — desktop discoverability only */
body[data-mobile-layout="true"] .search-flow-hint {
    display: none !important;
}

/* Toasts above the mobile search footer */
body[data-mobile-layout="true"] .app-notification {
    bottom: max(4.75rem, calc(env(safe-area-inset-bottom) + 3.75rem));
    max-width: min(420px, calc(100vw - 1.25rem));
}

/* ── Modals: mobile sheet ──
   Touch-only, mirroring isMobileLayout() in mobile-experience.js. Width alone
   would turn every narrow desktop window into a full-screen sheet. */
@media (hover: none) and (pointer: coarse) and (max-width: 991px) {
    .modal-overlay.show .modal,
    .modal-overlay.show .modal.modal--mobile-sheet {
        width: 100% !important;
        max-width: none !important;
        margin: 0;
        border-radius: 0;
        min-height: min(100dvh, 100vh);
        max-height: min(100dvh, 100vh);
    }

    .modal-overlay.show .modal .modal-body {
        max-height: calc(100dvh - 9rem);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .modal-overlay.show .modal .modal-actions {
        flex-direction: column;
        align-items: stretch;
        gap: 0.5rem;
    }

    .modal-overlay.show .modal .modal-button {
        min-height: 44px;
        width: 100%;
        justify-content: center;
    }

    .shortcut-search .search-container {
        max-height: calc(100dvh - 2rem);
    }
}

/* ==== css/layout-modern.css ==== */
/* Modern layout overrides — scoped to body[data-layout-version="modern"].
   Classic layout (default) is unchanged; all rules live in dashboard.css.

   Tokens (--layout-*, --modern-*) come from layout-modern-tokens.css, which
   loads first. Do not redefine them here. */

/* ─── Shared focus ring ──────────────────────────────────────────────────── */

body[data-layout-version="modern"] .page-nav-btn:focus-visible,
body[data-layout-version="modern"] .page-overview-header-btn:focus-visible,
body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor:focus-visible,
body[data-layout-version="modern"] .health-link a:focus-visible,
body[data-layout-version="modern"] .config-link a:focus-visible,
body[data-layout-version="modern"] .search-button:focus-visible,
body[data-layout-version="modern"] .tag-filter-indicator-chip:focus-visible,
body[data-layout-version="modern"] .tag-filter-indicator-clear:focus-visible,
body[data-layout-version="modern"] .page-overview-close:focus-visible,
body[data-layout-version="modern"] .page-overview-link:focus-visible,
body[data-layout-version="modern"] .page-overview-modal-link:focus-visible,
body[data-layout-version="modern"] .skip-to-content:focus-visible {
    outline: var(--layout-focus-ring);
    outline-offset: 2px;
}

/* ─── Skip link ──────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .skip-to-content {
    border-radius: var(--layout-radius-sm);
    background: var(--background-secondary);
    border-color: var(--border-primary);
    box-shadow: var(--layout-shadow-sm);
}

/* ─── Header shell ───────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-section.section-controls {
    padding-bottom: 1.15rem;
    border-bottom: 1px solid color-mix(in srgb, var(--border-primary) 32%, transparent);
    overflow-x: clip;
    max-width: 100%;
}

body[data-layout-version="modern"] .header-top {
    gap: var(--layout-gap-header) 1.5rem;
    align-items: flex-start;
    min-width: 0;
    max-width: 100%;
}

body[data-layout-version="modern"] .header-top-primary {
    flex-shrink: 0;
}

/* Centre the row: the children are different heights (the page-tab strip is a
   container with its own padding, the rest are single controls), so without
   this they align to the top and the pills sit a few pixels above the strip. */
body[data-layout-version="modern"] .header-actions {
    gap: var(--header-control-gap, 0.5rem);
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    min-width: 0;
    flex: 1 1 auto;
    max-width: 100%;
}

/* Classic pulled health/config back by 1rem when they sat in the main header
   row gap. Destinations now share .header-destinations (0.5rem) instead. */
body[data-layout-version="modern"] .health-link--icon,
body[data-layout-version="modern"] .config-link--icon,
body[data-layout-version="modern"] .pages-link--icon {
    margin-left: 0;
}

body[data-layout-version="modern"] .header-destinations {
    gap: var(--header-control-gap, 0.5rem);
}

/* ─── Date & status ──────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .date-time-line {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    padding: 0.2rem 0.55rem;
    margin: -0.2rem -0.55rem;
    border-radius: var(--layout-radius-sm);
    transition:
        opacity var(--layout-transition),
        background-color var(--layout-transition);
}

body[data-layout-version="modern"] .date-time-line:hover {
    opacity: 1;
    background: color-mix(in srgb, var(--background-secondary) 70%, transparent);
}

body[data-layout-version="modern"] .date-weather-line {
    color: color-mix(in srgb, var(--text-tertiary) 88%, var(--text-secondary));
}

body[data-layout-version="modern"] .dashboard-mini-status {
    padding: 0.15rem 0.5rem;
    border-radius: var(--layout-radius-pill);
    background: color-mix(in srgb, var(--background-secondary) 55%, transparent);
    border: 1px solid color-mix(in srgb, var(--border-primary) 35%, transparent);
}

/* ─── Header links (health / config) ─────────────────────────────────────── */

body[data-layout-version="modern"] .health-link a,
body[data-layout-version="modern"] .config-link a,
body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor,
body[data-layout-version="modern"] .header-destinations .page-nav-btn--inbox {
    display: inline-flex;
    align-items: center;
    padding: 0.38rem 0.8rem;
    border-radius: var(--layout-radius-pill);
    border: 1px solid var(--layout-surface-border);
    background: var(--layout-surface);
    transition:
        color var(--layout-transition),
        border-color var(--layout-transition),
        background-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .health-link a:hover,
body[data-layout-version="modern"] .config-link a:hover,
body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor:hover,
body[data-layout-version="modern"] .header-destinations .page-nav-btn--inbox:hover {
    color: var(--text-primary);
    border-color: color-mix(in srgb, var(--accent-primary) 40%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-secondary));
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .health-link a {
    animation: none;
    text-shadow: none;
}

/* ─── Pages overview button ──────────────────────────────────────────────── */

body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor,
body[data-layout-version="modern"] .page-overview-header-btn {
    padding: 0.38rem 0.8rem;
    border-radius: var(--layout-radius-pill);
    border: 1px solid var(--layout-surface-border);
    background: var(--layout-surface);
    transition:
        color var(--layout-transition),
        border-color var(--layout-transition),
        background-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .page-overview-header-btn:hover,
body[data-layout-version="modern"] .page-overview-header-btn:focus-visible,
body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor:hover,
body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor:focus-visible {
    border-color: color-mix(in srgb, var(--accent-primary) 40%, var(--border-primary));
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-secondary));
    box-shadow: var(--layout-shadow-sm);
}

/* ─── Page tabs ──────────────────────────────────────────────────────────── */

/* The page-tab strip is its own pill; the pages overview icon sits beside it,
   then inbox · health · config share .header-destinations — all at .header-actions gap. */
body[data-layout-version="modern"] .page-navigation {
    gap: 0.2rem;
    padding: 0.18rem;
    border-radius: var(--layout-radius-pill);
    background: var(--layout-surface);
    border: 1px solid var(--layout-surface-border);
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: thin;
}

body[data-layout-version="modern"] .page-nav-btn[data-view-tab] {
    background: var(--layout-surface);
    box-shadow: inset 0 0 0 1px var(--layout-surface-border);
}

body[data-layout-version="modern"] .page-nav-btn {
    border-bottom: none;
    border-radius: var(--layout-radius-pill);
    padding: 0.22rem 0.7rem;
    transition:
        color var(--layout-transition),
        background-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .page-nav-btn:hover {
    color: var(--text-primary);
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
}

body[data-layout-version="modern"] .page-nav-btn.active {
    background: color-mix(in srgb, var(--accent-primary) 16%, var(--background-secondary));
    color: var(--text-primary);
    font-weight: var(--font-weight-bold);
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 32%, transparent),
        var(--layout-shadow-sm);
}

/* Modern marks the current tab with a tinted pill rather than an underline; the
   health and config icons are the same kind of destination, so they follow suit
   here too. */
body[data-layout-version="modern"] .health-link--icon a.active,
body[data-layout-version="modern"] .config-link--icon a.active,
body[data-layout-version="modern"] .header-destinations .page-nav-btn--inbox.active {
    background: color-mix(in srgb, var(--accent-primary) 16%, var(--background-secondary));
    color: var(--text-primary);
    border-bottom-color: transparent;
    /* Modern is a fully-rounded pill (no underline), so restore the bottom radius
       the default layout squares off for its straight underline. */
    border-bottom-left-radius: var(--layout-radius-sm, 8px);
    border-bottom-right-radius: var(--layout-radius-sm, 8px);
    box-shadow:
        inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 32%, transparent),
        var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .page-tab-popover {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

body[data-layout-version="modern"] .page-tab-popover-icon,
body[data-layout-version="modern"] .page-tab-popover-name {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .move-popover {
    border-radius: var(--layout-radius-md);
    border-color: var(--layout-surface-border, var(--border-primary));
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

body[data-layout-version="modern"] .move-popover-item {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .move-popover-item.is-focused {
    background: color-mix(in srgb, var(--accent-primary) 14%, var(--background-primary));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 22%, transparent);
}

/* ─── Title section ──────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-section.section-title {
    padding-top: 0.35rem;
}

body[data-layout-version="modern"] .title {
    opacity: 0.94;
    letter-spacing: -0.015em;
    line-height: 1.15;
}

/* ─── Tag filter chip (header) ───────────────────────────────────────────── */

body[data-layout-version="modern"] .tag-filter-indicator-chip {
    border-radius: var(--layout-radius-pill);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .tag-filter-indicator-clear {
    border-radius: var(--layout-radius-pill);
}

/* ─── Bottom toolbar (center dock) ───────────────────────────────────────── */

body[data-layout-version="modern"]:not([data-button-position="side-left"]) .button-container {
    width: fit-content;
    max-width: min(52rem, calc(100vw - 2.5rem));
    padding: 0.55rem 0.8rem 0.65rem;
    border-radius: var(--layout-radius-lg);
    background: var(--layout-surface);
    border: 1px solid var(--layout-surface-border);
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    gap: 0.45rem;
}

/* Collapse button groups when every child is disabled via settings */
body[data-layout-version="modern"][data-show-add-bookmark-button="false"][data-show-search-button="false"][data-show-commands-button="false"][data-show-finders-button="false"] .btn-group-primary {
    display: none !important;
}

body[data-layout-version="modern"] .search-button {
    border-radius: var(--layout-radius-md);
    background: color-mix(in srgb, var(--background-primary) 68%, transparent);
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        color var(--layout-transition),
        transform var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .search-button:hover {
    background: var(--layout-surface);
    border-color: var(--layout-surface-border);
    color: var(--text-primary);
    transform: translateY(-1px);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .search-button:active {
    transform: translateY(0);
    box-shadow: none;
}

body[data-layout-version="modern"] .search-button[data-tooltip]::after {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-sm);
}

/* ─── Side dock button groups ────────────────────────────────────────────── */

body[data-layout-version="modern"][data-button-position="bottom-left"] .button-container,
body[data-layout-version="modern"][data-button-position="bottom-right"] .button-container {
    padding: 0;
    border: none;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body[data-layout-version="modern"][data-button-position="bottom-left"] .btn-group,
body[data-layout-version="modern"][data-button-position="bottom-right"] .btn-group {
    width: fit-content;
    padding: 0.4rem;
    border-radius: var(--layout-radius-md);
    background: var(--layout-surface);
    border: 1px solid var(--layout-surface-border);
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

/* ─── Tag cloud toggle (corner when not in rail) ─────────────────────────── */

body[data-layout-version="modern"] .tag-cloud-toggle-btn.search-button {
    border-radius: var(--layout-radius-md);
    background: var(--layout-surface);
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

/* ─── Side rail: rail only (no bottom dock / corner FAB duplicate) ─────────── */

body[data-layout-version="modern"][data-button-position="side-left"] .button-container {
    width: var(--rail-width, 44px);
    max-width: var(--rail-width, 44px);
    padding: 0;
    border-radius: 0;
    border-top: none;
    border-bottom: none;
    border-left: none;
    gap: 0;
}

body[data-layout-version="modern"][data-button-position="side-left"] .search-button {
    border-radius: 0;
    border: none;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body[data-layout-version="modern"][data-button-position="side-left"] .search-button:hover {
    transform: translateX(2px);
    box-shadow: none;
}

body[data-layout-version="modern"][data-button-position="side-left"] .search-button:active {
    transform: translateX(0);
}

body[data-layout-version="modern"][data-button-position="side-left"] .tag-cloud-toggle-btn.search-button {
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* ─── Date popover ─────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .date-popover {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-lg);
    border-color: var(--layout-surface-border, var(--border-primary));
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

body[data-layout-version="modern"] .date-popover-day {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .date-popover-day.is-today {
    background: color-mix(in srgb, var(--accent-primary) 18%, var(--background-primary));
    box-shadow: var(--layout-shadow-sm);
}

/* ─── Motion preferences ───────────────────────────────────────────────────── */

body[data-layout-version="modern"].no-animations .search-button:hover,
body[data-layout-version="modern"].no-animations .search-button:active,
body[data-layout-version="modern"].no-animations .tag-filter-indicator-chip:hover {
    transform: none !important;
}

/* ─── Responsive (modern only) ───────────────────────────────────────────── */

@media (max-width: 991px) {
    body[data-layout-version="modern"] .page-navigation {
        max-width: 100%;
        overflow-x: auto;
        flex-wrap: nowrap;
        scrollbar-width: thin;
        -webkit-overflow-scrolling: touch;
    }

    body[data-layout-version="modern"] .page-nav-btn {
        flex-shrink: 0;
    }
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    body[data-layout-version="modern"]:not([data-mobile-layout="true"]):not([data-button-position="side-left"]) .button-container {
        border-radius: var(--layout-radius-md);
        padding: 0.5rem 0.55rem 0.58rem;
    }

    body[data-layout-version="modern"] .search-button-labeled {
        border-radius: var(--layout-radius-sm);
    }

    body[data-layout-version="modern"] .header-actions {
        width: 100%;
        justify-content: flex-start;
    }

    body[data-layout-version="modern"] .page-navigation {
        width: 100%;
    }
}

@media (max-width: 575px) {
    body[data-layout-version="modern"] .dashboard-section.section-controls {
        padding-bottom: 0.85rem;
    }

    body[data-layout-version="modern"] .health-link a,
    body[data-layout-version="modern"] .config-link a,
    body[data-layout-version="modern"] .pages-link--icon .pages-link-anchor,
    body[data-layout-version="modern"] .header-destinations .page-nav-btn--inbox,
    body[data-layout-version="modern"] .page-overview-header-btn {
        padding: 0.32rem 0.62rem;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Phase 2 — Bookmark grid (all presets, density, badges, preview cards)
   ═══════════════════════════════════════════════════════════════════════════ */

body[data-layout-version="modern"] .dashboard-grid {
    --modern-row-radius: var(--layout-radius-sm);
    --modern-category-radius: var(--layout-radius-md);
}

/* ─── Category headers ───────────────────────────────────────────────────── */

body[data-layout-version="modern"] .category-title {
    letter-spacing: 0.04em;
    transition:
        color var(--layout-transition),
        background-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .category-title:hover {
    border-radius: var(--layout-radius-sm);
    padding: 0.15rem 0.45rem;
    margin: -0.15rem -0.45rem;
    background: color-mix(in srgb, var(--background-secondary) 72%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border-primary) 35%, transparent);
}

body[data-layout-version="modern"] .smart-collection-title {
    letter-spacing: 0.03em;
}

body[data-layout-version="modern"] .smart-collection-why-btn {
    border-radius: var(--layout-radius-pill);
}

body[data-layout-version="modern"] .smart-collection-why-popover {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-md);
}

/* ─── Shared bookmark row chrome ─────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link {
    border-radius: var(--modern-row-radius);
    transition:
        color var(--layout-transition),
        background-color var(--layout-transition),
        box-shadow var(--layout-transition),
        transform var(--layout-transition);
}

body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--modern-bookmark-row-hover-bg);
    box-shadow: none;
    border-radius: var(--modern-row-radius);
}

body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    background: var(--modern-bookmark-row-selected-bg);
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .bookmark-superscript-badge,
body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .status-text,
body[data-layout-version="modern"] .dashboard-grid:not(.layout-launcher) .bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) .bookmark-shortcut {
    background: transparent;
    border-color: color-mix(in srgb, var(--accent-primary) 35%, var(--border-secondary));
    color: var(--text-secondary);
}

body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid:not(.layout-launcher) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-offline-fg, var(--accent-error));
    background: color-mix(in srgb, var(--accent-error) 18%, var(--background-secondary));
    box-shadow: inset 3px 0 0 var(--status-offline-bar, var(--accent-error));
    font-weight: var(--font-weight-semibold, 600);
}

body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid:not(.layout-launcher) .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-checking-fg, var(--accent-warning));
    background: color-mix(in srgb, var(--accent-warning) 12%, var(--background-secondary));
}

body[data-layout-version="modern"] .bookmark-shortcut {
    border-radius: var(--layout-radius-sm);
    background: color-mix(in srgb, var(--background-secondary) 88%, transparent);
}

body[data-layout-version="modern"] .bookmark-superscript-badge,
body[data-layout-version="modern"] .bookmark-tag-chip {
    border-radius: var(--layout-radius-pill);
}

body[data-layout-version="modern"] .bookmark-note-badge[data-note-tooltip]::after {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .bookmark-icon-slot {
    border-radius: var(--layout-radius-sm);
    overflow: hidden;
}

body[data-layout-version="modern"] .bookmarks-list.reorder-container .bookmark-drop-placeholder,
body[data-layout-version="modern"].bookmark-dragging .bookmarks-list.reorder-container:not([data-smart-collection="true"]):not(:has(.bookmark-link))::after {
    border-radius: var(--modern-row-radius);
}

/* ─── Default preset ───────────────────────────────────────────────────────── */

body[data-layout-version="modern"][data-layout-preset="default"] .dashboard-grid {
    row-gap: 2.75rem;
    column-gap: 1.35rem;
}

body[data-layout-version="modern"][data-layout-preset="default"] .category {
    gap: 0.85rem;
}

/* ─── Compact preset ─────────────────────────────────────────────────────── */

body[data-layout-version="modern"][data-layout-preset="compact"] .dashboard-grid {
    row-gap: 1.35rem;
    column-gap: 0.9rem;
}

body[data-layout-version="modern"][data-layout-preset="compact"] .category {
    gap: 0.55rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-compact .bookmarks-list {
    gap: 0.22rem;
}

/* ─── Cards preset ─────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid.layout-cards .category {
    border-radius: var(--modern-category-radius);
    background: color-mix(in srgb, var(--background-secondary) 58%, var(--background-primary));
    border-color: color-mix(in srgb, var(--border-primary) 55%, transparent);
    box-shadow: var(--layout-shadow-sm);
    padding: 1rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-cards .bookmark-link {
    border-radius: var(--layout-radius-sm);
    background: transparent;
    border: none;
    box-shadow: none;
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .dashboard-grid.layout-cards .bookmark-link:hover:not(.bookmark-inline-editing) {
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary));
    border-color: transparent;
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid.layout-cards .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--modern-bookmark-row-selected-bg);
    border-color: color-mix(in srgb, var(--accent-primary) 30%, transparent);
    box-shadow: none;
}

/* ─── Terminal preset ────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .category-title-label::before {
    color: color-mix(in srgb, var(--accent-primary) 70%, var(--text-tertiary));
}

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .bookmark-link {
    border-radius: var(--layout-radius-sm);
    background: color-mix(in srgb, var(--background-secondary) 35%, transparent);
}

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .bookmark-link::before {
    color: var(--accent-primary);
    opacity: 0.8;
}

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .bookmark-link:hover:not(.bookmark-inline-editing) {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary));
}

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--modern-bookmark-row-selected-bg);
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid.layout-terminal .bookmark-shortcut {
    border-radius: var(--layout-radius-sm);
    font-family: var(--font-family-main, "Source Code Pro", monospace);
}

/* ─── Masonry preset ─────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid.layout-masonry .category {
    gap: 0.65rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-masonry .bookmark-link {
    border-radius: var(--layout-radius-sm);
    border: 1px solid color-mix(in srgb, var(--border-primary) 38%, transparent);
    background: color-mix(in srgb, var(--background-secondary) 48%, transparent);
    padding-inline: 0.55rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-masonry .bookmark-link:hover:not(.bookmark-inline-editing) {
    border-color: color-mix(in srgb, var(--accent-primary) 36%, var(--border-primary));
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .dashboard-grid.layout-masonry .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--modern-bookmark-row-selected-bg);
    border-color: color-mix(in srgb, var(--accent-primary) 36%, var(--border-primary));
    box-shadow: none;
}

/* ─── List preset ──────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid.layout-list .category {
    gap: 0.35rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-list .bookmark-link {
    border-radius: 0;
    padding: 0.6rem 0.4rem;
    margin-bottom: 0;
    background: transparent;
    border-bottom: 1px solid var(--border-primary);
}

body[data-layout-version="modern"] .dashboard-grid.layout-list .bookmark-link:hover:not(.bookmark-inline-editing) {
    border-radius: 0;
    background: color-mix(in srgb, var(--accent-primary) 11%, var(--background-secondary));
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid.layout-list .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    border-radius: 0;
    color: var(--text-primary);
    background: var(--modern-bookmark-row-selected-bg);
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid.layout-list .bookmark-text {
    line-height: 1.35;
}

/* ─── Widgets preset ───────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .dashboard-grid.layout-widgets .category {
    border-radius: var(--layout-radius-lg);
    background: color-mix(in srgb, var(--background-secondary) 62%, var(--background-primary));
    border-color: color-mix(in srgb, var(--border-primary) 50%, transparent);
    box-shadow: var(--layout-shadow-md);
    padding: 1.1rem;
}

body[data-layout-version="modern"] .dashboard-grid.layout-widgets .bookmark-link {
    border-radius: var(--layout-radius-sm);
    background: transparent;
    border: none;
    box-shadow: none;
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .dashboard-grid.layout-widgets .bookmark-link:hover:not(.bookmark-inline-editing) {
    background: color-mix(in srgb, var(--accent-primary) 8%, var(--background-primary));
    border-color: transparent;
    box-shadow: none;
}

body[data-layout-version="modern"] .dashboard-grid.layout-widgets .bookmark-link:is(.keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    color: var(--text-primary);
    background: var(--modern-bookmark-row-selected-bg);
    border-color: transparent;
    box-shadow: none;
}

/* ─── Launcher preset ────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .layout-launcher .category-title {
    padding: 0.1rem 0.35rem;
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .layout-launcher .bookmark-link {
    border-radius: var(--layout-radius-md);
    background: color-mix(in srgb, var(--background-secondary) 55%, transparent);
    border: 1px solid color-mix(in srgb, var(--border-primary) 42%, transparent);
    box-shadow: var(--layout-shadow-sm);
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        box-shadow var(--layout-transition),
        transform var(--layout-transition);
}

body[data-layout-version="modern"] .layout-launcher .bookmark-link:hover {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary));
    border-color: color-mix(in srgb, var(--accent-primary) 38%, var(--border-primary));
    box-shadow: var(--layout-shadow-md);
    transform: translateY(-2px);
}

body[data-layout-version="modern"] .layout-launcher .bookmark-link.keyboard-selected,
body[data-layout-version="modern"] .layout-launcher .bookmark-link:focus-within {
    background: color-mix(in srgb, var(--accent-primary) 16%, var(--background-secondary));
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-primary));
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"].bookmark-kbd-selection-dimmed .dashboard-grid:not(.layout-launcher) .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) {
    background: var(--modern-bookmark-row-dimmed-bg);
    box-shadow: none;
}

body[data-layout-version="modern"].bookmark-kbd-selection-dimmed .layout-launcher .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) {
    background: color-mix(in srgb, var(--accent-primary) 6%, var(--background-secondary));
    border-color: color-mix(in srgb, var(--accent-primary) 18%, var(--border-primary));
    box-shadow: var(--layout-shadow-sm);
    transform: none;
}

body[data-layout-version="modern"] .layout-launcher .bookmark-icon-slot {
    border-radius: var(--layout-radius-sm);
}

/* ─── Density modes ──────────────────────────────────────────────────────── */

body[data-layout-version="modern"][data-density-mode="comfortable"] .bookmarks-list {
    gap: 0.48rem;
}

body[data-layout-version="modern"][data-density-mode="compact"] .bookmarks-list,
body[data-layout-version="modern"][data-density-mode="auto"] .bookmarks-list {
    gap: 0.28rem;
}

body[data-layout-version="modern"][data-density-mode="dense"] .bookmarks-list {
    gap: 0.14rem;
}

body[data-layout-version="modern"][data-density-mode="comfortable"] .dashboard-grid:not(.layout-launcher) .bookmark-link {
    min-height: 2.15rem;
}

body[data-layout-version="modern"][data-density-mode="dense"] .dashboard-grid:not(.layout-launcher) .bookmark-link {
    min-height: 1.55rem;
    column-gap: 0.4rem;
}

/* ─── Badge visibility polish ────────────────────────────────────────────── */

body[data-layout-version="modern"][data-show-shortcuts="true"] .bookmark-shortcut:not(.is-empty) {
    opacity: 1;
}

body[data-layout-version="modern"][data-show-pin-icon="true"] .bookmark-pin-badge:not(.is-empty),
body[data-layout-version="modern"][data-show-note-icon="true"] .bookmark-note-badge:not(.is-empty) {
    background: color-mix(in srgb, var(--background-secondary) 90%, transparent);
    border-color: color-mix(in srgb, var(--border-primary) 55%, transparent);
}

/* ─── Link preview cards ───────────────────────────────────────────────────── */

body[data-layout-version="modern"] .bookmark-preview-card {
    border-radius: var(--layout-radius-lg);
    border-color: var(--layout-surface-border);
    background: color-mix(in srgb, var(--background-secondary) 92%, transparent);
    box-shadow: var(--layout-shadow-lg);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
}

body[data-layout-version="modern"] .bookmark-preview-card-refresh {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .bookmark-preview-card-image-wrap {
    border-bottom: 1px solid color-mix(in srgb, var(--border-primary) 35%, transparent);
}

/* ─── Inline edit & tag filter view ────────────────────────────────────────── */

body[data-layout-version="modern"] .bookmark-link.bookmark-inline-editing,
body[data-layout-version="modern"] .bookmark-link.bookmark-inline-editing:hover,
body[data-layout-version="modern"] .bookmark-link.bookmark-inline-editing.keyboard-selected,
body[data-layout-version="modern"] .bookmark-link.bookmark-inline-editing:focus-within {
    background: transparent;
    border: none;
    box-shadow: none;
    transform: none;
}

body[data-layout-version="modern"] .layout-launcher .bookmark-link.bookmark-inline-editing {
    width: auto;
    min-width: min(420px, 90vw);
    max-width: min(520px, 95vw);
    flex: 1 1 100%;
    align-items: stretch;
    padding: 0;
}

body[data-layout-version="modern"] .bookmark-inline-form {
    background-color: var(--inline-edit-panel-bg);
    border: 2px solid color-mix(in srgb, var(--border-primary) 70%, var(--text-secondary));
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"] .bookmark-inline-input,
body[data-layout-version="modern"] .bookmark-inline-select,
body[data-layout-version="modern"] .bookmark-inline-action-btn,
body[data-layout-version="modern"] .bookmark-inline-icon-preview {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] #dashboard-layout.tag-filter-view .tag-filter-indicator-chip {
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .tag-ac-dropdown {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-md);
}

/* ─── Grid motion preferences ──────────────────────────────────────────────── */

body[data-layout-version="modern"].no-animations .layout-launcher .bookmark-link:hover {
    transform: none !important;
}

body[data-layout-version="modern"].no-animations .dashboard-grid:not(.layout-launcher) .bookmark-link:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    transition: none !important;
}

/* ─── Grid responsive (modern) ─────────────────────────────────────────────── */

@media (max-width: 991px) {
    body[data-layout-version="modern"] .dashboard-grid.layout-cards .category,
    body[data-layout-version="modern"] .dashboard-grid.layout-widgets .category {
        padding: 0.85rem;
    }

    body[data-layout-version="modern"] .dashboard-grid.layout-list .bookmark-link {
        padding: 0.5rem 0.4rem;
    }
}

@media (max-width: 768px), (hover: none) and (pointer: coarse) {
    body[data-layout-version="modern"] .layout-launcher .bookmark-link {
        border-radius: var(--layout-radius-md);
    }

    body[data-layout-version="modern"] .layout-launcher .bookmark-link:hover {
        transform: none;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Phase 4 — Mobile modern layout
   ═══════════════════════════════════════════════════════════════════════════ */

body[data-layout-version="modern"][data-mobile-layout="true"] .mobile-experience-banner {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"][data-mobile-layout="true"] .mobile-experience-banner-dismiss {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"][data-mobile-layout="true"] .dashboard-section.section-controls {
    padding-bottom: 0.75rem;
}

body[data-layout-version="modern"][data-mobile-layout="true"] #page-overview-header-btn,
body[data-layout-version="modern"][data-mobile-layout="true"] .pages-link--icon .pages-link-anchor,
body[data-layout-version="modern"][data-mobile-layout="true"] .config-link a,
body[data-layout-version="modern"][data-mobile-layout="true"] .header-destinations .page-nav-btn--inbox {
    border-radius: var(--layout-radius-pill);
    border: 1px solid var(--layout-surface-border);
    background: var(--layout-surface);
}

body[data-layout-version="modern"][data-mobile-layout="true"] #page-overview-header-btn:active,
body[data-layout-version="modern"][data-mobile-layout="true"] .pages-link--icon .pages-link-anchor:active,
body[data-layout-version="modern"][data-mobile-layout="true"] .config-link a:active,
body[data-layout-version="modern"][data-mobile-layout="true"] .header-destinations .page-nav-btn--inbox:active {
    background: color-mix(in srgb, var(--accent-primary) 12%, var(--background-secondary));
    border-color: color-mix(in srgb, var(--accent-primary) 40%, var(--border-primary));
}

body[data-layout-version="modern"][data-mobile-layout="true"] .button-container {
    width: fit-content;
    max-width: calc(100% - 2rem);
    border-radius: var(--layout-radius-lg);
    padding: 0.5rem 0.65rem 0.58rem;
}

body[data-layout-version="modern"][data-mobile-layout="true"] .btn-group-primary {
    width: auto;
    gap: 0.45rem;
}

body[data-layout-version="modern"][data-mobile-layout="true"] .search-button-labeled {
    border-radius: var(--layout-radius-md);
    min-height: 44px;
}

body[data-layout-version="modern"][data-mobile-layout="true"] .shortcut-search .search-container {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-lg);
}

body[data-layout-version="modern"][data-mobile-layout="true"] .search-mode-tab {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"][data-mobile-layout="true"] .app-notification {
    border-radius: var(--layout-radius-md);
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"][data-mobile-layout="true"] .dashboard-grid .category-title:hover {
    margin: -0.15rem -0.35rem;
    padding: 0.15rem 0.35rem;
}

body[data-layout-version="modern"][data-mobile-layout="true"] .dashboard-grid:not(.layout-launcher) .bookmark-link {
    min-height: 44px;
}

/* ─── Status row colors (override preset chrome) ─────────────────────────── */

body[data-layout-version="modern"]:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-offline-fg, var(--accent-error, #ef4444));
    background: color-mix(in srgb, var(--accent-error, #ef4444) 22%, var(--background-secondary));
    box-shadow: inset 3px 0 0 var(--status-offline-bar, var(--accent-error, #ef4444));
    font-weight: var(--font-weight-semibold, 600);
}

body[data-layout-version="modern"]:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-checking-fg, var(--accent-warning, #f59e0b));
    background: color-mix(in srgb, var(--accent-warning, #f59e0b) 14%, var(--background-secondary));
}

body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid.layout-list .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid.layout-cards .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid.layout-masonry .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid.layout-terminal .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing),
body[data-layout-version="modern"]:not(.status-color-lock) .dashboard-grid.layout-widgets .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:not(:hover):not(.keyboard-selected):not(:focus-within):not(.bookmark-inline-editing) {
    color: var(--status-offline-fg, var(--accent-error, #ef4444));
    background: color-mix(in srgb, var(--accent-error, #ef4444) 24%, var(--background-secondary));
    box-shadow: inset 3px 0 0 var(--status-offline-bar, var(--accent-error, #ef4444));
}

body[data-layout-version="modern"]:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-offline:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing),
body[data-layout-version="modern"]:not(.status-color-lock) .bookmarks-list[data-bookmarks-list="true"]:not([data-smart-collection="true"]) .bookmark-link.status-checking:is(:hover, .keyboard-selected, :focus-within):not(.bookmark-inline-editing) {
    border-radius: var(--modern-row-radius, 4px);
}

body[data-layout-version="modern"].bookmark-kbd-selection-dimmed .dashboard-grid:not(.layout-launcher) .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .bookmark-superscript-badge,
body[data-layout-version="modern"].bookmark-kbd-selection-dimmed .dashboard-grid:not(.layout-launcher) .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .status-text,
body[data-layout-version="modern"].bookmark-kbd-selection-dimmed .dashboard-grid:not(.layout-launcher) .bookmark-link.keyboard-selected:not(:hover):not(.bookmark-inline-editing) .bookmark-shortcut {
    background: color-mix(in srgb, var(--background-primary) 70%, transparent);
    border-color: color-mix(in srgb, var(--border-primary) 55%, transparent);
    color: var(--text-tertiary);
}

/* ─── Empty dashboard states (page / fresh) ───────────────────────────────── */

body[data-layout-version="modern"] #dashboard-layout > .empty-state {
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 2rem 1.5rem;
    box-sizing: border-box;
    border-radius: var(--layout-radius-md);
    border: 1px solid var(--layout-surface-border);
    background: var(--layout-surface);
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .dashboard-grid.layout-cards .smart-collection-empty,
body[data-layout-version="modern"] .dashboard-grid.layout-widgets .smart-collection-empty {
    border-style: solid;
    border-color: color-mix(in srgb, var(--layout-surface-border) 85%, transparent);
    background: color-mix(in srgb, var(--layout-surface) 72%, transparent);
}

/* ==== css/overlays-modern.css ==== */
/* Modern overlay UI — search, modals, toasts, tag cloud, selects.
   Scoped to body[data-layout-version="modern"]. Classic unchanged.

   Tokens (--layout-*) come from layout-modern-tokens.css, which loads first.
   Do not redefine them here. */

/* ─── Search overlay ───────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .shortcut-search {
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
}

body[data-layout-version="modern"] .search-container {
    border-radius: var(--layout-radius-lg);
    border-color: var(--layout-surface-border);
    background: var(--layout-surface);
    box-shadow: var(--layout-shadow-md);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

body[data-layout-version="modern"]:not([data-button-position="side-left"]):not([data-button-position="bottom-left"]):not([data-button-position="bottom-right"]) .search-container {
    width: min(52rem, calc(100vw - 2.5rem));
    max-width: 100%;
}

body[data-layout-version="modern"] .search-prefix {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .search-match {
    border-radius: var(--layout-radius-sm);
    border-left: none;
}

body[data-layout-version="modern"] .search-match:hover,
body[data-layout-version="modern"] .search-match.keyboard-selected {
    background: color-mix(in srgb, var(--accent-primary) 11%, var(--background-secondary));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 24%, transparent);
}

body[data-layout-version="modern"] .search-command-group-header {
    margin-top: 0.35rem;
    padding: 0.45rem 0.55rem 0.25rem;
    border-top: none;
    border-radius: var(--layout-radius-sm);
    opacity: 0.72;
}

body[data-layout-version="modern"] .search-command-group-header:hover,
body[data-layout-version="modern"] .search-command-group-header.keyboard-selected {
    opacity: 1;
    background: color-mix(in srgb, var(--background-primary) 55%, transparent);
}

body[data-layout-version="modern"] .search-command-group-header.keyboard-selected {
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 22%, transparent);
}

body[data-layout-version="modern"] .search-mode-tabs {
    gap: 0.35rem;
    padding: 0.35rem;
    margin-top: 0.5rem;
    border-top: none;
    border-radius: var(--layout-radius-md);
    background: var(--background-secondary);
    border: 1px solid var(--border-primary);
}

body[data-layout-version="modern"] .search-mode-tab {
    border-radius: var(--layout-radius-pill);
    border: 1px solid transparent;
    transition:
        color var(--layout-transition),
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .search-mode-tab.active {
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .search-mode-tab:hover {
    background: color-mix(in srgb, var(--background-primary) 70%, transparent);
}

body[data-layout-version="modern"] .search-history-chip,
body[data-layout-version="modern"] .search-command-chip {
    border-radius: var(--layout-radius-pill);
    background: color-mix(in srgb, var(--background-secondary) 80%, transparent);
}

body[data-layout-version="modern"] .search-history-chip:hover,
body[data-layout-version="modern"] .search-command-chip:hover {
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-secondary));
}

/* ─── Modals ─────────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .modal-overlay {
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
}

body[data-layout-version="modern"] .modal {
    border-radius: var(--layout-radius-lg);
    box-shadow: var(--layout-shadow-lg);
    overflow: hidden;
    background: var(--layout-modal-bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body[data-layout-version="modern"] .modal-header {
    background: var(--background-secondary);
    border-bottom-color: color-mix(in srgb, var(--border-primary) 45%, transparent);
}

body[data-layout-version="modern"] .modal-body {
    background: var(--background-primary);
}

body[data-layout-version="modern"] .modal-new-bookmark {
    border-radius: var(--layout-radius-lg);
}

body[data-layout-version="modern"] .nbm-header {
    background: var(--background-secondary);
}

body[data-layout-version="modern"] .nbm-input,
body[data-layout-version="modern"] .nbm-select {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .nbm-input:focus,
body[data-layout-version="modern"] .nbm-select:focus {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 18%, transparent);
}

body[data-layout-version="modern"] .wn-intro {
    border-radius: var(--layout-radius-sm);
    background: var(--background-secondary);
}

body[data-layout-version="modern"] .wn-kofi-btn,
body[data-layout-version="modern"] .wn-release-tag {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .modal-button,
body[data-layout-version="modern"] .modal .btn {
    border-radius: var(--layout-radius-sm);
}

/* Dashboard + config toolbar modals — surface parity with search overlay */
body[data-layout-version="modern"]:has(#dashboard-layout) #app-modal.modal-overlay:has(.recent-bookmarks-modal) .modal,
body[data-layout-version="modern"]:has(#dashboard-layout) #app-modal.modal-overlay:has(.keyboard-cheat-sheet-modal) .modal,
body[data-layout-version="modern"]:has(#dashboard-layout) #app-modal.modal-overlay:has(.whats-new-modal) .modal,
body[data-layout-version="modern"]:has(#dashboard-layout) #app-modal.modal-overlay:has(.inbox-intro-modal) .modal,
body[data-layout-version="modern"]:has(#config-main) #app-modal.modal-overlay:has(.whats-new-modal) .modal {
    border-radius: var(--layout-radius-lg);
    border-color: var(--layout-surface-border);
    background: var(--layout-modal-bg);
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"] .recent-bookmarks-modal-item,
body[data-layout-version="modern"] .recent-bookmarks-skeleton-row,
body[data-layout-version="modern"] .page-overview-modal-link {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .recent-bookmarks-modal-item:hover,
body[data-layout-version="modern"] .page-overview-modal-link:hover,
body[data-layout-version="modern"] .page-overview-modal-item.is-focused .page-overview-modal-link {
    background: color-mix(in srgb, var(--accent-primary) 11%, var(--background-secondary));
    border-color: color-mix(in srgb, var(--accent-primary) 24%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-primary) 24%, transparent);
}

/* ─── Toasts ─────────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .app-notification {
    border-radius: var(--layout-radius-md);
    background: var(--background-secondary);
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"] .app-notification-action {
    border-radius: var(--layout-radius-sm);
}

/* ─── Tag cloud ──────────────────────────────────────────────────────────── */

body[data-layout-version="modern"] .tag-cloud-modal {
    border-radius: var(--layout-radius-lg);
    background: var(--background-secondary);
    border-color: var(--border-primary);
    box-shadow: var(--layout-shadow-lg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body[data-layout-version="modern"] .tag-cloud-modal-close {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .tag-cloud-modal-close:hover {
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-primary));
}

body[data-layout-version="modern"] .tag-cloud-word:hover,
body[data-layout-version="modern"] .tag-cloud-word.is-selected {
    border-radius: var(--layout-radius-sm);
    background: color-mix(in srgb, var(--accent-primary) 12%, transparent);
}

body[data-layout-version="modern"] .tag-cloud-clear-filter {
    border-radius: var(--layout-radius-pill);
}

/* ─── Custom selects (dashboard + config) ────────────────────────────────── */

body[data-layout-version="modern"] .custom-select-trigger {
    border-radius: var(--layout-radius-sm);
    transition:
        border-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .custom-select.open .custom-select-trigger,
body[data-layout-version="modern"] .custom-select-trigger:focus-visible {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 16%, transparent);
}

body[data-layout-version="modern"] .custom-select-options {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"] .custom-select-option:hover,
body[data-layout-version="modern"] .custom-select-option.selected {
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-primary));
}

/* Tag autocomplete (config bookmarks form — portaled to body) */
body[data-layout-version="modern"] .tag-ac-dropdown {
    border-radius: var(--layout-radius-sm);
    box-shadow: var(--layout-shadow-md);
}

body[data-layout-version="modern"] .tag-ac-item:hover,
body[data-layout-version="modern"] .tag-ac-item-active {
    background: color-mix(in srgb, var(--accent-primary) 10%, var(--background-secondary));
    border-radius: var(--layout-radius-sm);
}

/* ─── Feature tour (dashboard onboarding) ────────────────────────────────── */

body[data-layout-version="modern"] .feature-tour-card {
    border-radius: var(--layout-radius-lg);
    box-shadow: var(--layout-shadow-lg);
    background: var(--layout-overlay-bg);
}

body[data-layout-version="modern"] .feature-tour-input,
body[data-layout-version="modern"] .feature-tour-fieldset {
    border-radius: var(--layout-radius-sm);
}

body[data-layout-version="modern"] .feature-tour-input:focus {
    outline: none;
    border-color: color-mix(in srgb, var(--accent-primary) 45%, var(--border-primary));
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-primary) 16%, transparent);
}

body[data-layout-version="modern"] .feature-tour-btn {
    border-radius: var(--layout-radius-sm);
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        box-shadow var(--layout-transition);
}

body[data-layout-version="modern"] .feature-tour-btn:hover:not(:disabled) {
    box-shadow: var(--layout-shadow-sm);
}

body[data-layout-version="modern"] .feature-tour-focus-ring {
    border-radius: var(--layout-radius-sm);
}

/* ─── Config guided tours ─────────────────────────────────────────────────── */

body[data-layout-version="modern"] [class*="-tour-card"] {
    border-radius: var(--layout-radius-lg);
    box-shadow: var(--layout-shadow-lg);
    background: var(--layout-overlay-bg);
}

body[data-layout-version="modern"] [class*="-tour-card"] .btn,
body[data-layout-version="modern"] [class*="-tour-card"] button {
    border-radius: var(--layout-radius-sm);
}

/* ==== css/layout-side-rail.css ==== */
/* Side Rail navigation — body[data-rail]
   Converts the bottom button bar into a 44px vertical rail on a screen edge.
   All other layouts (classic / modern) are unaffected.

   The rail exists on both edges. Rather than duplicating every rule for
   side-right, the selectors match a side-agnostic [data-rail] hook and the few
   properties that actually carry a direction read from variables below. Adding
   the right-hand rail is then the variable block, not 68 mirrored rules.

   --rail-edge / --rail-edge-far: which physical side the rail is pinned to.
   --rail-out: the direction "away from the rail", used by tooltips and popovers
   that must open over the content rather than off-screen. */

/* ── Variables ─────────────────────────────────────────────────────────────── */
body[data-rail] {
    --rail-width: 44px;
    --rail-bg: color-mix(in srgb, var(--background-secondary) 88%, transparent);
    --rail-border: color-mix(in srgb, var(--border-primary) 45%, transparent);
    --rail-btn-radius: 0.45rem;
    --rail-btn-padding: 0.62rem 0;
    --rail-sep-color: color-mix(in srgb, var(--border-primary) 35%, transparent);
}

/* Left rail (default) and its mirror. Only these two blocks know about sides. */
body[data-button-position="side-left"] {
    --rail-edge: 0;
    --rail-edge-far: auto;
    --rail-out: 1;               /* content lies to the right */
}

body[data-button-position="side-right"] {
    --rail-edge: auto;
    --rail-edge-far: 0;
    --rail-out: -1;              /* content lies to the left */
    /* Tooltips and hints open leftward, over the content, not off-screen. */
    --rail-tip-left: auto;
    --rail-tip-right: calc(100% + 8px);
    --rail-hint-left: auto;
    --rail-hint-right: calc(var(--rail-width) + 0.65rem);
    --rail-content-left: 0;
    --rail-content-right: var(--rail-width);
    --rail-border-right: none;
    --rail-border-left: 1px solid var(--rail-border);
}

/* ── Rail container ─────────────────────────────────────────────────────────── */
body[data-rail] .button-container {
    position: fixed;
    left: var(--rail-edge);
    right: var(--rail-edge-far);
    top: 0;
    bottom: 0;
    transform: none;
    width: var(--rail-width);
    max-width: var(--rail-width);

    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-items: stretch;

    /* bottom room for ! + ★ fixed elements */
    padding: 0 0 calc(var(--corner-fab-height, 2.75rem) * 2 + 0.3rem);
    gap: 0;

    background: var(--rail-bg);
    /* The divider faces the content, so it swaps sides with the rail. */
    border-right: var(--rail-border-right, 1px solid var(--rail-border));
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);

    /* Above tag-cloud-wrap (1001) and toggle (1002) so rail buttons receive events */
    z-index: 1003;
    overflow: visible;
    box-shadow: none;
    border-radius: 0;
    border-top: none;
    border-bottom: none;
    border-left: var(--rail-border-left, none);
}

/* ── Button groups: flatten into rail flex flow ──────────────────────────────── */
body[data-rail] .btn-group {
    display: contents;
}

/* ── Button order & spacers ──────────────────────────────────────────────────── */
/* 1. add bookmark — top */
body[data-rail] #quick-add-toolbar-btn   { order: 1; }
/* spacer (one button height) before search */
body[data-rail] #search-button           { order: 2; margin-top: var(--corner-fab-height, 2.75rem); }
/* finders before commands */
body[data-rail] #finders-button          { order: 3; }
body[data-rail] #commands-button         { order: 4; }
body[data-rail] #recent-bookmarks-button { order: 5; }
body[data-rail] #tag-cloud-toggle-btn { order: 6; }

/* cheatsheet: fixed directly above the what's new button */
body[data-rail] #help-button {
    position: fixed;
    bottom: var(--corner-fab-height, 2.75rem);
    left: 0;
    width: var(--rail-width);
    height: var(--corner-fab-height, 2.75rem);
    padding: 0;
    justify-content: center;
    border-radius: 0;
    border-top: 1px solid var(--rail-sep-color);
    border-left: none;
    border-right: none;
    border-bottom: none;
    background: transparent;
    transform: none;
    z-index: 1004;
    order: unset;
    margin-top: 0;
}

/* ── Individual buttons: same style as what's new ────────────────────────────── */
body[data-rail] .search-button {
    width: var(--rail-width);
    height: var(--corner-fab-height, 2.75rem);
    padding: 0;
    margin: 0;
    justify-content: center;
    border-radius: 0;
    border: none;
    background: transparent;
    min-width: 0;
    box-shadow: none;
}

body[data-rail] .search-button-labeled {
    flex-direction: column;
    min-width: 0;
    gap: 0;
}

body[data-rail] .search-button-label {
    display: none !important;
}

body[data-rail] .search-button:hover {
    transform: translateX(calc(var(--rail-out, 1) * 2px));
    background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
    border-color: var(--accent-primary);
    box-shadow: none;
}

body[data-rail] .search-button:active {
    transform: translateX(0);
}

body[data-rail] #help-button:hover {
    transform: translateX(calc(var(--rail-out, 1) * 2px));
    background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
    border-color: var(--accent-primary);
    box-shadow: none;
}

/* ── Tooltips: show to the right of the rail ─────────────────────────────────── */
body[data-rail] .search-button[data-tooltip]::after {
    bottom: auto;
    top: 50%;
    left: var(--rail-tip-left, calc(100% + 8px));
    right: var(--rail-tip-right, auto);
    transform: translateY(-50%);
    white-space: nowrap;
}

/* ── Tag cloud: in rail flow directly under recents ─────────────────────────── */
body[data-rail] #tag-cloud-toggle-btn.search-button {
    position: static;
    width: var(--rail-width);
    height: var(--corner-fab-height, 2.75rem);
    padding: 0;
    margin: 0;
    justify-content: center;
    border-radius: 0;
    border: none;
    border-top: 1px solid var(--rail-sep-color);
    background: transparent;
    transform: none;
    z-index: auto;
    pointer-events: auto;
}

body[data-rail] #tag-cloud-toggle-btn[data-tooltip]::after {
    bottom: auto;
    top: 50%;
    left: var(--rail-tip-left, calc(100% + 8px));
    right: var(--rail-tip-right, auto);
    transform: translateY(-50%);
    white-space: nowrap;
}

body[data-rail] #tag-cloud-toggle-btn:hover {
    transform: translateX(calc(var(--rail-out, 1) * 2px));
    background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
}

/* ── What's new button: anchor to rail bottom ────────────────────────────────── */
body[data-rail] .whats-new-btn {
    left: var(--rail-edge);
    right: var(--rail-edge-far);
    bottom: 0;
    width: var(--rail-width);
    height: calc(var(--corner-fab-height, 2.75rem));
    padding: 0;
    justify-content: center;
    border-radius: 0;
    border-top: 1px solid var(--rail-sep-color);
    border-left: none;
    border-right: none;
    border-bottom: none;
    background: transparent;
    z-index: 1004;
}

body[data-rail] .whats-new-btn:hover {
    transform: translateX(calc(var(--rail-out, 1) * 2px));
    box-shadow: none;
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
}

body[data-rail] .whats-new-btn[data-tooltip]::after {
    bottom: auto;
    top: 50%;
    left: var(--rail-tip-left, calc(100% + 8px));
    right: var(--rail-tip-right, auto);
    transform: translateY(-50%);
}

/* ── Hints: beside the rail (parity with bottom-toolbar discoverability) ───── */
body[data-rail] .search-flow-hint {
    position: fixed;
    left: var(--rail-hint-left, calc(var(--rail-width) + 0.65rem));
    right: var(--rail-hint-right, auto);
    top: calc(var(--corner-fab-height, 2.75rem) * 2 + 0.35rem);
    bottom: auto;
    transform: none;
    justify-content: flex-start;
    align-items: flex-start;
    max-width: min(13.5rem, calc(100vw - var(--rail-width) - 1.5rem));
    z-index: 1002;
    pointer-events: none;
}

body[data-rail] .search-flow-hint-text {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 0.12rem 0.3rem;
    text-align: left;
    line-height: 1.45;
}

body[data-rail] .search-flow-hint-text > .sfh-seg:nth-child(even) {
    display: none;
}

/* ── One-time side-rail legend (icon → label map) ───────────────────────────── */
.side-rail-legend {
    position: fixed;
    left: var(--rail-hint-left, calc(var(--rail-width) + 0.65rem));
    right: var(--rail-hint-right, auto);
    top: calc(var(--corner-fab-height, 2.75rem) + 0.35rem);
    z-index: 1002;
    width: min(13.5rem, calc(100vw - var(--rail-width) - 1.5rem));
    margin: 0;
    padding: 0.55rem 0.65rem 0.5rem;
    border: 1px solid color-mix(in srgb, var(--border-primary) 55%, transparent);
    border-radius: var(--layout-radius-sm, 8px);
    background: color-mix(in srgb, var(--background-secondary) 92%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 4px 18px color-mix(in srgb, var(--text-primary) 10%, transparent);
    color: var(--text-secondary);
    font-size: calc(var(--font-size-controls) * 0.95);
    line-height: 1.35;
    pointer-events: auto;
}

.side-rail-legend[hidden] {
    display: none !important;
}

.side-rail-legend.is-dismissing {
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity 0.35s ease, transform 0.35s ease;
}

.side-rail-legend-title {
    margin: 0 0 0.35rem;
    font-size: calc(var(--font-size-controls) * 0.88);
    font-weight: var(--font-weight-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.side-rail-legend-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.18rem;
}

.side-rail-legend-item {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
    min-width: 0;
}

.side-rail-legend-key {
    flex-shrink: 0;
    min-width: 1.15rem;
    text-align: center;
    color: var(--accent-primary);
    font-weight: var(--font-weight-semibold);
}

.side-rail-legend-label {
    min-width: 0;
    color: var(--text-primary);
}

.side-rail-legend-foot {
    margin: 0.4rem 0 0.45rem;
    font-size: calc(var(--font-size-controls) * 0.88);
    color: var(--text-tertiary);
}

.side-rail-legend-dismiss {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    padding: 0.28rem 0.55rem;
    border: 1px solid var(--border-primary);
    border-radius: var(--layout-radius-xs, 4px);
    background: var(--background-primary);
    color: var(--text-primary);
    font: inherit;
    font-size: calc(var(--font-size-controls) * 0.92);
    cursor: pointer;
}

.side-rail-legend-dismiss:hover {
    border-color: var(--accent-primary);
    color: var(--accent-primary);
}

body[data-rail] .side-rail-legend kbd {
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: none;
    background: none;
    padding: 0;
    color: inherit;
}

/* ── Content area: shift right to clear the rail ────────────────────────────── */
body[data-rail] .container {
    margin-left: var(--rail-content-left, var(--rail-width));
    margin-right: var(--rail-content-right, 0);
}

/* ── Page section: reduce bottom padding (no floating bar) ───────────────────── */
body[data-rail] .dashboard-section.section-content {
    padding-bottom: 3rem;
}

/* ── Page tabs: keep numbers/names visible (respect showPageNamesInTabs) ─────── */
body[data-rail] .page-nav-btn {
    font-size: var(--font-size-controls);
    padding: 0.4rem 0.6rem;
    min-width: 0;
}

body[data-rail] .page-tab-dot {
    display: inline-block;
    width: 0.45em;
    height: 0.45em;
    margin-right: 0.35em;
    vertical-align: middle;
    flex-shrink: 0;
}

body[data-rail] .page-tab-icon {
    display: inline;
}

body[data-rail] .page-nav-btn.active {
    background: var(--background-secondary);
    border-bottom-color: var(--accent-primary);
}

body[data-rail] .page-nav-btn.active .page-tab-dot {
    box-shadow: none;
    width: 0.45em;
    height: 0.45em;
}

body[data-rail] .page-nav-btn:hover .page-tab-dot {
    box-shadow: none;
}

/* ── Inline bookmark edit: keep rail visible ─────────────────────────────────── */
body.bookmark-inline-edit-active[data-rail] .button-container {
    opacity: 1;
    pointer-events: auto;
}

/* ── Prevent no-animations from re-centering the rail ────────────────────────── */
body.no-animations[data-rail] .button-container {
    transform: none !important;
}

/* ── Modern layout overrides ─────────────────────────────────────────────────── */
body[data-layout-version="modern"][data-rail] .button-container {
    background: var(--layout-surface);
    border-right-color: var(--layout-surface-border);
    box-shadow: 2px 0 12px color-mix(in srgb, var(--text-primary) 8%, transparent);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

body[data-layout-version="modern"][data-rail] .search-button {
    transition:
        background-color var(--layout-transition),
        border-color var(--layout-transition),
        color var(--layout-transition),
        transform var(--layout-transition);
}

body[data-layout-version="modern"][data-rail] .whats-new-btn {
    background: transparent;
    border-top-color: var(--layout-surface-border);
}
/* ── Mobile: fall back to centered bottom bar ────────────────────────────────── */
@media (max-width: 768px) {
    body[data-rail] .button-container {
        position: fixed;
        left: 50%;
        top: auto;
        bottom: 2rem;
        transform: translateX(-50%);
        width: min(52rem, calc(100vw - 2.5rem));
        max-width: 100%;
        height: auto;
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
        padding: 0.7rem 0 0;
        gap: 0;
        background: transparent;
        border-right: none;
        border: 0;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        box-shadow: none;
        border-radius: 0;
    }

    /* undo display:contents so groups become rows again */
    body[data-rail] .btn-group {
        display: flex;
        flex-direction: row;
        width: auto;
        padding: 0;
        gap: 0.55rem;
    }

    /* reset button ordering and spacers */
    body[data-rail] #quick-add-toolbar-btn,
    body[data-rail] #search-button,
    body[data-rail] #finders-button,
    body[data-rail] #commands-button,
    body[data-rail] #recent-bookmarks-button,
    body[data-rail] #tag-cloud-toggle-btn,
    body[data-rail] #help-button {
        order: unset;
        margin-top: 0;
    }

    /* tag cloud: back into toolbar flow on mobile */
    body[data-rail] #tag-cloud-toggle-btn.search-button {
        position: static;
        left: auto;
        right: auto;
        bottom: auto;
        width: auto;
        padding: 0.62rem 0.82rem;
        margin: 0;
        transform: none;
        border-top: none;
    }

    /* cheatsheet: back into normal flow on mobile */
    body[data-rail] #help-button {
        position: static;
        bottom: auto;
        left: auto;
        width: auto;
        z-index: auto;
    }

    body[data-rail] .search-button {
        padding: 0.62rem 0.92rem;
        width: auto;
        height: auto;
        border-radius: 0.65rem;
        border: 1px solid var(--border-primary);
        background: var(--button-secondary-bg, var(--background-secondary));
    }

    body[data-rail] .search-button:hover {
        transform: none;
    }

    body[data-rail] .container {
        margin-left: 0;
    }

    body[data-rail] .dashboard-section.section-content {
        padding-bottom: 8rem;
    }

    body[data-rail] .page-nav-btn {
        font-size: var(--font-size-controls);
        padding: 0.4rem 0.6rem;
    }

    body[data-rail] .page-tab-dot {
        width: 0.45em;
        height: 0.45em;
        margin-right: 0.35em;
    }

    body[data-rail] .page-tab-icon {
        display: inline;
    }

    body[data-rail] .page-nav-btn.active .page-tab-dot {
        box-shadow: none;
        width: 0.45em;
        height: 0.45em;
    }

    body[data-rail] .tag-cloud-toggle-btn.search-button {
        left: auto;
        right: var(--corner-fab-edge, 1.5rem);
        bottom: calc(var(--corner-fab-edge, 1.5rem) + var(--corner-fab-height, 2.75rem) + var(--corner-fab-gap, 0.4rem));
        width: auto;
        padding: 0.62rem 0.82rem;
        margin: 0;
        transform: none;
    }

    body[data-rail] #tag-cloud-toggle-btn.search-button {
        position: static;
        right: auto;
        bottom: auto;
    }

    body[data-rail] .whats-new-btn {
        left: auto;
        right: var(--corner-fab-edge, 1.5rem);
        bottom: var(--corner-fab-edge, 1.5rem);
        width: auto;
        height: auto;
        padding: 0.62rem 0.72rem;
        border-radius: 0.65rem;
        border-top: 1px solid var(--border-primary);
    }

    body.no-animations[data-rail] .button-container {
        transform: translateX(-50%) !important;
    }

    body[data-rail] .search-flow-hint {
        position: absolute;
        left: 0;
        right: 0;
        top: auto;
        bottom: calc(100% + 0.85rem);
        max-width: none;
        justify-content: center;
        align-items: center;
    }

    body[data-rail] .search-flow-hint-text {
        flex-wrap: nowrap;
        justify-content: center;
        text-align: center;
    }

    body[data-rail] .search-flow-hint-text > .sfh-seg:nth-child(even) {
        display: inline;
    }

    body[data-rail] .side-rail-legend {
        display: none !important;
    }
}

/* ==== css/dashboard-inline-edit-surface.css ==== */
/* Inline edit opaque surfaces — loaded last; wins over layout tokens. */

body.bookmark-inline-edit-active {
    --inline-edit-panel-bg: var(--background-primary);
    --inline-edit-field-bg: var(--background-secondary);
}

@supports (background: rgb(from red r g b)) {
    body.bookmark-inline-edit-active {
        --inline-edit-panel-bg: rgb(from var(--background-primary) r g b / 1);
        --inline-edit-field-bg: rgb(from var(--background-secondary) r g b / 1);
    }
}

body.bookmark-inline-edit-active .bookmark-link.bookmark-inline-editing {
    background: var(--inline-edit-panel-bg);
    border-radius: 8px;
    padding: 0.35rem;
    box-shadow: 0 16px 48px color-mix(in srgb, var(--text-primary) 22%, transparent);
}

body.bookmark-inline-edit-active .layout-launcher .bookmark-link.bookmark-inline-editing {
    padding: 0;
    background: transparent;
    box-shadow: none;
}

body.bookmark-inline-edit-active .bookmark-inline-form {
    background: var(--inline-edit-panel-bg);
    background-image: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

body.bookmark-inline-edit-active .bookmark-inline-form .bookmark-inline-input,
body.bookmark-inline-edit-active .bookmark-inline-form .bookmark-inline-select,
body.bookmark-inline-edit-active .bookmark-inline-form .bookmark-inline-textarea,
body.bookmark-inline-edit-active .bookmark-inline-form .bookmark-inline-action-btn,
body.bookmark-inline-edit-active .bookmark-inline-form .bookmark-inline-icon-preview {
    background: var(--inline-edit-field-bg);
}

/* ==== css/reduced-motion.css ==== */
/* Global reduced-motion honouring.
 *
 * Animation suppression used to be opt-in per component: each effect paired a
 * `body.no-animations` rule (the in-app setting) with a matching
 * prefers-reduced-motion block. That left gaps — newer stylesheets such as
 * dashboard-tag-cloud.css and layout-side-rail.css never got the second half,
 * so an infinitely pulsing FAB kept running for someone who had asked their OS
 * to stop exactly that.
 *
 * The OS preference is an accessibility signal, not a styling preference, so it
 * wins outright rather than being merged with the in-app toggle. There is
 * deliberately no escape hatch: animationsEnabled defaults to true and is a
 * plain bool, so "explicitly on" is indistinguishable from "never touched" —
 * any opt-out would fire for every default user and undo the whole rule.
 *
 * Loaded last so this beats the `!important` declarations components already
 * use. Durations are near-zero rather than `animation: none`, because code that
 * waits on animationend (see dashboard-visual.js showHealthAlert) still needs
 * the event to fire; `none` would strand those listeners.
 */

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

/* ==== css/fonts.css ==== */
/* Self-hosted Source Code Pro (variable font) — replaces the Google Fonts CDN.
 * One woff2 per subset covers all weights (200–900). Keeps the app offline-first
 * and avoids a render-blocking third-party request. */

/* latin-ext (accented Latin, extra currency/symbol glyphs) */
@font-face {
    font-family: 'Source Code Pro';
    font-style: normal;
    font-weight: 200 900;
    font-display: swap;
    src: url('/static/fonts/source-code-pro-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* latin (ASCII + common punctuation/symbols) */
@font-face {
    font-family: 'Source Code Pro';
    font-style: normal;
    font-weight: 200 900;
    font-display: swap;
    src: url('/static/fonts/source-code-pro-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
