/* Layout */
.appLayout {
    display: flex;
    height: 100vh;
    padding-top: var(--header-height);
}

/* Sidebar — row-flex container that holds a dark `.foldersPane` on the left
   and a light `.notesPane` on the right. Background-less itself; each pane
   paints its own. */
.sidebar {
    width: 440px;
    min-width: 320px;
    display: flex;
    flex-direction: row;
    overflow: hidden;
    position: relative;
    border-right: 1px solid var(--border);
    transition: transform var(--transition), opacity var(--transition), margin-left var(--transition);
}

.sidebar.hidden {
    margin-left: calc(-1 * var(--sidebar-hidden-offset, 440px));
    opacity: 0;
    pointer-events: none;
}

/* Folders pane — carries the .darkSidebar class so /common/css/theme.css
   maps it into a dark variable scope (every active theme defines its own
   dark sidebar palette). The pane's children (folders, folder header,
   footer) inherit the dark vars without affecting anything outside. */
.foldersPane {
    width: 220px;
    min-width: 160px;
    flex-shrink: 0;
    /* Resolve color against the dark scope above so children that inherit
       get the right text color instead of the light-theme value from <body>. */
    color: var(--text);
    background: var(--bg-sidebar);
    border-right: 1px solid rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Anchor for the right-edge resize handle. */
    position: relative;
}

/* Drag handle on the right edge of the folders pane — mirrors the
   .sidebarResizer pattern but resizes only the folders pane width. */
.foldersPaneResizer {
    position: absolute;
    top: 0;
    right: -3px;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    z-index: 21;
    transition: background var(--transition);
}

.foldersPaneResizer::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 1px;
    height: 100%;
    background: transparent;
    transition: background var(--transition), width var(--transition);
}

.foldersPaneResizer:hover::after,
body.isResizingFoldersPane .foldersPaneResizer::after {
    background: var(--border-strong);
    width: 2px;
}

body.isResizingFoldersPane {
    cursor: col-resize;
    user-select: none;
}

body.isResizingFoldersPane * {
    cursor: col-resize !important;
    user-select: none !important;
}

/* Notes pane — light, matches the editor background so the editor and
   notes list read as one continuous surface. */
.notesPane {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--bg);
}

/* Header above the notes list with back button (mobile only), pane title,
   and the new-note button that used to live in the app header.
   Height + horizontal padding match .editorToolbar so the in-pane sidebar
   toggle lands in the exact same screen position as the editor toolbar's
   toggle — popping the overlay open feels like the button stayed put. */
.notesPaneHeader {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 48px;
    padding: 0 12px;
    flex-shrink: 0;
}

.notesPaneBack {
    display: none;
    width: 30px;
    height: 30px;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    font-size: 13px;
    transition: background var(--transition), color var(--transition),
                border-color var(--transition);
    flex-shrink: 0;
}

.notesPaneBack:hover {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border-strong);
}

/* Sidebar-toggle pinned at the start of each pane header on mobile. Lets
   the user dismiss the sidebar overlay without having to scroll back to
   the editor toolbar. Hidden on desktop where the sidebar is permanent.
   Carries a "Sidebar" label so the affordance is self-evident. */
.sidebarPaneToggle {
    display: none;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: -0.005em;
    cursor: pointer;
    transition: background var(--transition), color var(--transition),
                border-color var(--transition);
    flex-shrink: 0;
}

.sidebarPaneToggle .fa-table-columns { font-size: 14px; }

.sidebarPaneToggle:hover {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border-strong);
}

/* Shared with .editorToolbarToggle. Inline-block so the icon-only state
   on tiny screens collapses cleanly to a square. */
.sidebarToggleLabel {
    display: inline;
}

/* Folder pane sits on a dark surface where bg-hover (a dim near-black)
   would actually darken further on hover. Use a translucent light tint
   instead so the icon color flip remains visible. */
.foldersPane .sidebarPaneToggle {
    color: rgba(255, 255, 255, 0.7);
}
.foldersPane .sidebarPaneToggle:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
}

.notesPaneTitle {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    letter-spacing: -0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.notesPaneNewBtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    /* Auto-sizes to content: icon-only instances (e.g., the mobile header)
       collapse to a square; instances with a .notesPaneNewBtnLabel grow to
       fit the text. min-height keeps both forms visually consistent. */
    min-width: 30px;
    min-height: 30px;
    padding: 0 10px;
    border-radius: var(--radius-sm);
    background: var(--accent);
    /* Icon color is the inverse of the pane background, so the same button
       reads as dark-on-light in the notes pane and light-on-dark in the
       folders pane (where --bg-sidebar / --accent are inverted). */
    color: var(--bg-sidebar);
    font-size: 15px;
    font-weight: 500;
    /* Matches .headerBtnPrimary — hairline inner highlight + soft drop
       shadow for tactile elevation. Keeps primary CTAs across the app
       visually unified. */
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10),
                inset 0 1px 0 rgba(255, 255, 255, 0.08);
    transition: background 120ms ease, color 120ms ease,
                box-shadow 160ms ease, transform 120ms ease;
    flex-shrink: 0;
}

/* Tighter padding when the button is icon-only (no label child). */
.notesPaneNewBtn:not(:has(.notesPaneNewBtnLabel)) {
    padding: 0;
    width: 30px;
}

.notesPaneNewBtnLabel {
    font-size: 13.5px;
    font-weight: 500;
    letter-spacing: -0.005em;
    white-space: nowrap;
}

.notesPaneNewBtn:hover {
    box-shadow: 0 3px 8px rgba(0, 0, 0, 0.16),
                inset 0 1px 0 rgba(255, 255, 255, 0.12);
    transform: translateY(-0.5px);
}

.notesPaneNewBtn:active {
    transform: translateY(0);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.10),
                inset 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* Hardcoded black-tint hovers don't read on the dark folders pane — bump to
   a light-tint equivalent inside that scope. */
.foldersPane .folderChevron:hover,
.foldersPane .folderIconEmoji:hover {
    background: rgba(255, 255, 255, 0.08);
}

/* Sidebar resize handle */
.sidebarResizer {
    position: absolute;
    top: 0;
    right: -3px;
    width: 6px;
    height: 100%;
    cursor: col-resize;
    z-index: 20;
    transition: background var(--transition);
}

.sidebarResizer::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 1px;
    height: 100%;
    background: transparent;
    transition: background var(--transition), width var(--transition);
}

.sidebarResizer:hover::after,
body.isResizing .sidebarResizer::after {
    background: var(--border-strong);
    width: 2px;
}

body.isResizing {
    cursor: col-resize;
    user-select: none;
}

body.isResizing * {
    cursor: col-resize !important;
    user-select: none !important;
}

.foldersList {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    /* Padding moved here from the now-removed .foldersSection wrapper so
       folder rows still get breathing room on the sides. */
    padding: 0 8px 8px;
}

.folderRow {
    display: flex;
    flex-direction: column;
}

.folderItem {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 8px 8px 2px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
    transition: background var(--transition);
    position: relative;
    text-align: left;
    width: 100%;
    min-height: 28px;
}

.folderItem.noChevron {
    padding-left: 8px;
}

.folderItem.active {
    background: var(--bg-active);
    font-weight: 500;
}

/* Chevron for accordion */
.folderChevron {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 3px;
    color: var(--text-tertiary);
    font-size: 9px;
    flex-shrink: 0;
    transition: transform var(--transition), background var(--transition), color var(--transition);
}

.folderChevron:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--text);
}

.folderChevronPlaceholder {
    pointer-events: none;
}

.folderRow.expanded > .folderItem > .folderChevron {
    transform: rotate(90deg);
    color: var(--text-secondary);
}

/* Icon container — used for both FA icons and emojis */
.folderIconWrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: 4px;
    line-height: 1;
}

.folderIconFa i {
    font-size: 12px;
    color: var(--text-tertiary);
}

.folderIconEmoji {
    font-size: 14px;
    cursor: pointer;
    transition: background var(--transition), transform var(--transition);
}

.folderIconEmoji:hover {
    background: rgba(0, 0, 0, 0.06);
    transform: scale(1.08);
}

.folderItemName {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.folderItemCount {
    font-size: 11px;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
    padding-left: 4px;
}

.folderItemActions {
    display: flex;
    align-items: center;
    gap: 2px;
}

/* Desktop: hide the folder kebab. The note kebab (.noteItemActions) is
   defined further down (after .noteItemDelete) and gets its own desktop-
   hide rule next to that definition — same-specificity cascade rules
   mean we have to place that hide *after* the base, not up here. */
@media (min-width: 769px) {
    .folderItemActions {
        display: none;
    }
}

/* While the user is renaming a folder (mobile or desktop), the inline
   <input> takes over .folderItemName's slot — drop the kebab so it
   doesn't crowd the input or steal the tap when the user is reaching
   for the right end of the field. The actions menu is reachable again
   after the rename commits / cancels. */
.folderItem:has(.folderItemNameInput) .folderItemActions {
    display: none;
}

/* Nested notes inside an expanded folder */
.folderChildren {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin: 2px 0 4px 14px;
    padding-left: 10px;
    border-left: 1px solid var(--border);
}

.folderChildNote {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    color: var(--text-secondary);
    text-align: left;
    width: 100%;
    transition: background var(--transition), color var(--transition);
}

.folderChildNote:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.folderChildNote.active {
    background: var(--bg-active);
    color: var(--text);
    font-weight: 500;
}

.folderChildDot {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--text-tertiary);
    flex-shrink: 0;
    opacity: 0.7;
}

.folderChildNote.active .folderChildDot {
    background: var(--accent);
    opacity: 1;
}

.folderChildTitle {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

.folderChildEmpty {
    font-size: 11.5px;
    color: var(--text-tertiary);
    padding: 4px 8px;
    font-style: italic;
}

.folderItemAction {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    border-radius: var(--radius-sm);
    font-size: 14px;
    color: var(--text-tertiary);
    transition: all var(--transition);
}

.folderItemAction.danger:hover {
    background: rgba(220, 50, 50, 0.1);
    color: #c33;
}

.folderItemNameInput {
    flex: 1;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    padding: 2px 6px;
    font-size: 13px;
    font-family: inherit;
    color: var(--text);
    outline: none;
    min-width: 0;
}

/* Note folder menu */
.noteItemFolder {
    position: absolute;
    top: 8px;
    right: 36px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    font-size: 11px;
    color: var(--text-tertiary);
    opacity: 0;
    transition: all var(--transition);
}

.noteItem:hover .noteItemFolder {
    opacity: 1;
}

.noteItemFolder:hover {
    background: var(--bg-hover);
    color: var(--text);
}

/* Share / export popover */
.exportPopover {
    position: fixed;
    z-index: 120;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.1), 0 1px 4px rgba(0, 0, 0, 0.04);
    padding: 5px;
    min-width: 240px;
    display: none;
}

.exportPopover.open { display: block; }

/* Public-link toggle row at the top of the popover. */
.exportPopoverToggle {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px 10px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
}

.exportPopoverToggle:hover { background: var(--bg-hover); }

.exportPopoverToggleBody {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.exportPopoverToggleTitle {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
}

.exportPopoverToggleHint {
    font-size: 11.5px;
    color: var(--text-tertiary);
    line-height: 1.35;
}

.exportPopoverSwitch {
    position: relative;
    width: 34px;
    height: 20px;
    flex-shrink: 0;
}

.exportPopoverSwitch input {
    appearance: none;
    -webkit-appearance: none;
    position: absolute;
    inset: 0;
    margin: 0;
    cursor: pointer;
    opacity: 0;
}

.exportPopoverSwitchTrack {
    position: absolute;
    inset: 0;
    background: var(--border-strong);
    border-radius: 999px;
    transition: background var(--transition);
}

.exportPopoverSwitchTrack::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
    transition: transform var(--transition);
}

.exportPopoverSwitch input:checked + .exportPopoverSwitchTrack {
    background: var(--accent);
}

.exportPopoverSwitch input:checked + .exportPopoverSwitchTrack::after {
    transform: translateX(14px);
}

.exportPopoverDivider {
    height: 1px;
    background: var(--border);
    margin: 4px 6px;
}

.exportPopoverItem {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    width: 100%;
    text-align: left;
    cursor: pointer;
    transition: background var(--transition);
}

.exportPopoverItem:hover { background: var(--bg-hover); }

.exportPopoverItemIcon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background: var(--accent-soft);
    color: var(--text-secondary);
    font-size: 12px;
    flex-shrink: 0;
}

.exportPopoverItem:hover .exportPopoverItemIcon {
    background: var(--bg-active);
    color: var(--text);
}

.exportPopoverItemBody {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.exportPopoverItemTitle {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.exportPopoverItemHint {
    font-size: 11.5px;
    color: var(--text-tertiary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.folderPopover {
    position: fixed;
    z-index: 100;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
    padding: 4px;
    min-width: 180px;
    max-height: 280px;
    overflow-y: auto;
    display: none;
}

.folderPopover.open {
    display: block;
}

/* Folder actions overflow menu — opens from the kebab in each folder row. */
.folderActionsMenu {
    position: fixed;
    z-index: 110;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
    padding: 5px;
    min-width: 200px;
    display: none;
}

.folderActionsMenu.open { display: block; }

.folderActionsItem {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    color: var(--text);
    text-align: left;
    transition: background var(--transition);
}

.folderActionsItem:hover { background: var(--bg-hover); }

.folderActionsItem i {
    width: 16px;
    text-align: center;
    font-size: 12px;
    color: var(--text-secondary);
}

.folderActionsItem--danger { color: #c33; }
.folderActionsItem--danger i { color: #c33; }
.folderActionsItem--danger:hover { background: rgba(220, 50, 50, 0.08); }

.folderActionsDivider {
    height: 1px;
    background: var(--border);
    margin: 4px 6px;
}

.folderPopoverItem {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    font-size: 13px;
    color: var(--text);
    border-radius: var(--radius-sm);
    cursor: pointer;
    width: 100%;
    text-align: left;
}

.folderPopoverItem:hover {
    background: var(--bg-hover);
}

.folderPopoverItem.current {
    color: var(--primary);
}

.folderPopoverItem i {
    font-size: 11px;
    width: 14px;
    text-align: center;
    color: var(--text-tertiary);
}

.folderPopoverItem.current i {
    color: var(--primary);
}

.folderPopoverEmoji {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    font-size: 13px;
    line-height: 1;
}

.folderPopoverDivider {
    height: 1px;
    background: var(--border);
    margin: 4px 0;
}

/* Emoji picker popover */
.emojiPicker {
    position: fixed;
    /* Above .confirmModal (z-index: 300) so the picker floats ABOVE the
       new-folder modal when invoked from inside it. */
    z-index: 350;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
    padding: 10px;
    width: 280px;
    max-height: 360px;
    display: none;
    flex-direction: column;
    overflow: hidden;
}

.emojiPicker.open { display: flex; }

/* Tabs row at the top of the icon picker — switches between FA icons and
   the legacy emoji palette. */
.iconPickerTabs {
    display: flex;
    gap: 2px;
    padding: 2px 0 8px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
}

.iconPickerTab {
    flex: 1;
    padding: 5px 8px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    background: transparent;
    transition: background var(--transition), color var(--transition);
}

.iconPickerTab:hover { background: var(--bg-hover); color: var(--text); }
.iconPickerTab.active {
    background: var(--accent-soft);
    color: var(--text);
}

/* Search input above the icons grid — substring filter against the
   FA_ICON_PALETTE list. */
.iconPickerSearch {
    width: 100%;
    padding: 6px 10px;
    margin-bottom: 8px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    font-size: 13px;
    transition: border-color var(--transition);
    flex-shrink: 0;
}

.iconPickerSearch:focus { border-color: var(--border-strong); }

.iconPickerEmpty {
    grid-column: 1 / -1;
    text-align: center;
    padding: 20px 8px;
    font-size: 12px;
    color: var(--text-tertiary);
}

.emojiPickerHeader {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    padding: 2px 4px 8px;
}

.emojiPickerGrid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    /* Allow the grid to scroll inside the bounded picker — the FA list is
       long, the emoji list short; both share the same scroll container. */
    overflow-y: auto;
    flex: 1;
    min-height: 0;
}

.emojiOption {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    font-size: 18px;
    line-height: 1;
    border-radius: var(--radius-sm);
    background: transparent;
    transition: background var(--transition), transform var(--transition);
    cursor: pointer;
}

.emojiOption:hover {
    background: var(--bg-hover);
    transform: scale(1.1);
}

.emojiOption.selected {
    background: var(--accent-soft);
    box-shadow: inset 0 0 0 1px var(--border-strong);
}

.emojiPickerReset {
    display: block;
    width: 100%;
    margin-top: 8px;
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    color: var(--text-tertiary);
    transition: background var(--transition), color var(--transition);
    text-align: center;
}

.emojiPickerReset:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.sidebarSearch {
    padding: 0px 10px 10px 10px;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Wrapper around the input + its inline clear button. Takes the flex slot
   the input itself used to occupy so the row layout (search + sort) is
   unchanged. */
.sidebarSearchField {
    flex: 1;
    min-width: 0;
    position: relative;
    display: flex;
}

.sidebarSearch input {
    flex: 1;
    min-width: 0;
    /* Extra right padding leaves room for the absolutely-positioned × so
       typed text never slides under it. */
    padding: 8px 30px 8px 12px;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    font-size: 13px;
    transition: border-color var(--transition);
}

.sidebarSearch input:focus {
    border-color: var(--border-strong);
}

.sidebarSearch input::placeholder {
    color: var(--text-tertiary);
}

.sidebarSearchClear {
    display: none;
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 22px;
    height: 22px;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    border-radius: 999px;
    color: var(--text-tertiary);
    font-size: 11px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

.sidebarSearchClear:hover {
    background: var(--bg-hover);
    color: var(--text);
}

/* Show the clear only when the input has typed content. :placeholder-shown
   is true when the placeholder is visible (i.e., empty), so :not(...) is
   the "has content" state. Wrapped in :has() so the parent reacts. */
.sidebarSearchField:has(input:not(:placeholder-shown)) .sidebarSearchClear {
    display: flex;
}

/* Sort button — sits to the right of the search input. */
.sidebarSortBtn {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--text-secondary);
    font-size: 13px;
    transition: background var(--transition), color var(--transition), border-color var(--transition);
}

.sidebarSortBtn:hover {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border-strong);
}

.sidebarSortBtn.open {
    background: var(--accent-soft);
    border-color: var(--border-strong);
    color: var(--text);
}

/* Sort popover — fixed positioning, anchored to the sort button via JS. */
.sortPopover {
    position: fixed;
    z-index: 120;
    display: none;
    flex-direction: column;
    gap: 1px;
    min-width: 220px;
    padding: 5px;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
}

.sortPopover.open { display: flex; }

.sortPopoverHeader {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    padding: 6px 10px 4px;
}

.sortPopoverItem {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    color: var(--text);
    text-align: left;
    transition: background var(--transition);
}

.sortPopoverItem:hover {
    background: var(--bg-hover);
}

.sortPopoverItemLabel {
    flex: 1;
    min-width: 0;
}

.sortPopoverItemCheck {
    font-size: 11px;
    color: var(--accent);
    opacity: 0;
}

.sortPopoverItem.active .sortPopoverItemCheck {
    opacity: 1;
}

.sortPopoverItem.active .sortPopoverItemLabel {
    font-weight: 500;
}

.notesList {
    flex: 1;
    overflow-y: auto;
    padding: 0 8px 12px;
}

.noteItem {
    display: block;
    width: 100%;
    text-align: left;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 2px;
    transition: background var(--transition);
    position: relative;
}

.noteItem:hover {
    background: var(--bg-hover);
}

.noteItem.active {
    background: var(--bg-active);
}

.noteItemTitle {
    font-size: 13.5px;
    font-weight: 500;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text);
    margin-right: 60px;
}

/* Globe marker prefixed to a note's title in the list when the note is
   public. Subtle accent color so it doesn't compete with the title text. */
.noteItemPublicIcon {
    margin-right: 6px;
    font-size: 10.5px;
    color: var(--text-tertiary);
    vertical-align: 1px;
}

.noteItemPreview {
    font-size: 12px;
    color: var(--text-tertiary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 5px;
}

/* Tag chip strip below the preview line in the sidebar list. Single
   row, clipped via overflow so heavily-tagged notes don't elongate the
   row beyond what the rest of the list expects. */
.noteItemTags {
    display: flex;
    flex-wrap: nowrap;
    gap: 4px;
    margin-top: 5px;
    overflow: hidden;
    margin-right: 60px; /* clear the kebab affordance */
}
.noteItemTag {
    flex-shrink: 0;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
}
.noteItemTag--more {
    background: transparent;
    color: var(--text-tertiary);
    padding: 1px 4px;
}

.noteItemDate {
    font-size: 11px;
    color: var(--text-tertiary);
    margin-top: 3px;
}

.noteItemDelete {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    font-size: 11px;
    color: var(--text-tertiary);
    opacity: 0;
    transition: all var(--transition);
}

.noteItem:hover .noteItemDelete {
    opacity: 1;
}

.noteItemDelete:hover {
    background: rgba(220, 50, 50, 0.1);
    color: #c33;
}

/* Kebab overflow trigger on each note row — replaces the inline folder /
   delete icons with a single ⋯ that opens the shared #folderActionsMenu
   (so mobile sizing for that menu applies here too). */
.noteItemActions {
    position: absolute;
    top: 8px;
    right: 0px;
    width: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    color: var(--text-tertiary);
    font-size: 15px;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

/* Hide on desktop — right-click on the row opens the same menu. Mobile
   keeps the kebab visible since touch has no right-click. */
@media (min-width: 769px) {
    .noteItemActions {
        display: none;
    }
}

/* Confirmation modal */
.confirmModal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 300;
    align-items: center;
    justify-content: center;
}

.confirmModal.open {
    display: flex;
}

.confirmModalBackdrop {
    position: absolute;
    inset: 0;
    background: rgba(20, 20, 20, 0.32);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.confirmModalContent {
    position: relative;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.06);
    padding: 22px 22px 18px;
    width: 380px;
    max-width: calc(100% - 32px);
}

.confirmModalTitle {
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-bottom: 6px;
    color: var(--text);
}

.confirmModalBody {
    font-size: 13.5px;
    color: var(--text-secondary);
    line-height: 1.5;
    margin-bottom: 16px;
}

.confirmModalBody #deleteNoteName {
    color: var(--text);
    font-weight: 500;
}

.confirmModalInput {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--bg);
    font-size: 14px;
    color: var(--text);
    font-family: inherit;
    margin-bottom: 16px;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.confirmModalInput:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.confirmModalInput::placeholder {
    color: var(--text-tertiary);
}

/* Icon-picker button + name input row inside the create-folder modal. */
.newFolderRow {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin-bottom: 16px;
}

.newFolderRow .confirmModalInput {
    margin-bottom: 0;
    flex: 1;
    min-width: 0;
}

.newFolderIconBtn {
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--bg);
    color: var(--text);
    font-size: 18px;
    transition: background var(--transition), border-color var(--transition);
}

.newFolderIconBtn:hover {
    background: var(--bg-hover);
    border-color: var(--text-secondary);
}

.newFolderIconBtn i { font-size: 16px; }

.confirmModalCheckbox {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    color: var(--text-secondary);
    cursor: pointer;
    margin-bottom: 18px;
    user-select: none;
    padding: 6px 0;
}

.confirmModalCheckbox input {
    cursor: pointer;
    accent-color: var(--accent);
    width: 14px;
    height: 14px;
}

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

.confirmModalActions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.confirmModalBtn {
    padding: 7px 14px;
    border-radius: var(--radius-sm);
    font-size: 13px;
    font-weight: 500;
    transition: background var(--transition), color var(--transition), border-color var(--transition), opacity var(--transition);
    border: 1px solid transparent;
}

/* Disabled modal buttons read as clearly inactive — muted, non-clickable. */
.confirmModalBtn:disabled,
.confirmModalBtn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.confirmModalBtnCancel {
    color: var(--text-secondary);
    border-color: var(--border);
}

.confirmModalBtnCancel:hover {
    background: var(--bg-hover);
    color: var(--text);
    border-color: var(--border-strong);
}

.confirmModalBtnDanger {
    color: #fff;
    background: #c33;
}

.confirmModalBtnDanger:hover {
    background: #b02a2a;
}

.confirmModalBtnPrimary {
    color: #fff;
    background: var(--accent);
}

/* Account management modal — extends the confirm modal with section layout */
.accountModalContent {
    width: 460px;
    max-width: calc(100% - 32px);
    padding: 24px 22px 20px;
    position: relative;
}

.accountCloseBtn {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 28px;
    height: 28px;
    border-radius: 6px;
    background: transparent;
    border: none;
    color: var(--text-tertiary);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background var(--transition), color var(--transition);
}

.accountCloseBtn:hover {
    background: var(--bg-hover);
    color: var(--text);
}

.accountModalHeader {
    margin-bottom: 18px;
}

.accountModalSub {
    margin-top: 4px;
    font-size: 12.5px;
    color: var(--text-tertiary);
}

.accountModalSub strong {
    color: var(--text-secondary);
    font-weight: 600;
}

.accountSection {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.accountSectionTitle {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-tertiary);
}

.accountSectionBody {
    font-size: 12.5px;
    color: var(--text-secondary);
    line-height: 1.5;
}

.accountSectionDivider {
    height: 1px;
    background: var(--border);
    margin: 18px 0;
}

.accountForm {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.accountForm .confirmModalInput {
    margin-bottom: 0;
}

.accountFormRow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 4px;
    min-height: 30px;
}

.accountFormRowBtns {
    display: flex;
    gap: 8px;
    margin-left: auto;
}

.accountFormMsg {
    font-size: 12px;
    color: var(--text-tertiary);
    flex: 1;
    min-width: 0;
}

.accountFormMsg--ok { color: #2d7a4a; }
.accountFormMsg--error { color: #b33; }

.accountSection--danger .accountSectionTitle {
    color: #b33;
}

.accountDeleteConfirm {
    display: none;
    flex-direction: column;
    gap: 8px;
    margin-top: 6px;
    padding: 12px;
    border: 1px solid rgba(220, 50, 50, 0.25);
    border-radius: var(--radius-sm);
    background: rgba(220, 50, 50, 0.04);
}

.accountDeleteConfirm.open {
    display: flex;
}

.accountWarning {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 12px;
    border: 1px solid rgba(160, 106, 26, 0.25);
    background: rgba(160, 106, 26, 0.06);
    border-radius: var(--radius-sm);
    font-size: 12px;
    line-height: 1.5;
    color: #8a5a18;
}

.accountWarning i {
    margin-top: 2px;
    flex-shrink: 0;
}

.exportStatusChip {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 500;
    border: 1px solid var(--border);
    background: var(--bg-sidebar);
    color: var(--text-secondary);
}

.exportStatusChip--pending {
    background: rgba(160, 106, 26, 0.08);
    border-color: rgba(160, 106, 26, 0.25);
    color: #a06a1a;
}

/* URL hover hint (follows the cursor over editor links) */
.linkHoverTip {
    position: fixed;
    z-index: 500;
    max-width: 420px;
    padding: 5px 9px;
    border-radius: 5px;
    background: #1a1a1a;
    color: #f2f2f2;
    font-size: 11.5px;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 0.1s ease-out, transform 0.1s ease-out;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.linkHoverTip.open {
    opacity: 0.95;
    transform: translateY(0);
}

.confirmModalBtnPrimary:hover {
    background: #111;
}

.confirmModalBtnDanger:focus-visible,
.confirmModalBtnPrimary:focus-visible,
.confirmModalBtnCancel:focus-visible {
    outline: 2px solid var(--border-strong);
    outline-offset: 2px;
}

/* Empty state */
.emptyState {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Take the remaining space in the flex-column .mainContent (which now
       also hosts the always-visible .editorToolbar above us). */
    flex: 1;
    min-height: 0;
    color: var(--text-tertiary);
    text-align: center;
    padding: 40px;
}

.emptyState i {
    font-size: 32px;
    margin-bottom: 16px;
    opacity: 0.4;
}

.emptyState p {
    font-size: 14px;
    line-height: 1.6;
}

.emptyState .emptyHint {
    font-size: 12px;
    margin-top: 8px;
}

/* Footer */
.appFooter {
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    background: var(--bg-sidebar);
    font-size: 11px;
    color: var(--text-tertiary);
    text-align: center;
}

.appFooter a {
    color: var(--text-secondary);
}

.appFooter p + p {
    margin-top: 4px;
}

.appFooter strong {
    color: var(--text-secondary);
    font-weight: 600;
}

.appFooterMeta {
    opacity: 0.75;
}

/* Sync status pill (in header) — always visible. Sturdy, tactile pill with
   a fixed minimum width so the label can change ("Saved" → "Syncing…" →
   "Saved") without the surrounding header buttons jittering side-to-side.
   Inset highlight + subtle drop shadow give it physical presence. */
/* Sync status chip — minimal bordered chip with three states: checkmark
   (synced), spinning arrow (syncing), x-mark (offline). Sized to harmonize
   with the header buttons; label collapses on mobile so the icon alone
   carries the status. */
.syncStatus {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 32px;
    padding: 0 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--text-secondary);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: -0.005em;
    margin-right: 4px;
    white-space: nowrap;
    transition: color 200ms ease, border-color 200ms ease;
}

.syncStatusIcon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    font-size: 12px;
    line-height: 1;
}

.syncStatus.syncStatus--ok {
    color: #1f6b3d;
    border-color: rgba(45, 122, 74, 0.30);
}

.syncStatus.syncStatus--syncing {
    color: var(--text-secondary);
    border-color: var(--border-strong);
}

.syncStatus.syncStatus--offline {
    color: #a32424;
    border-color: rgba(160, 38, 38, 0.30);
}

.syncStatusLabel {
    /* Wrapper so the label collapses on narrow viewports while the icon
       stays as a quiet status indicator. */
    display: inline;
}

@media (max-width: 600px) {
    .syncStatus {
        width: 35px;
        padding: 0;
        gap: 0;
        margin-right: 0;
    }
    .syncStatusLabel { display: none; }
}

/* Toast notification (bottom-right, auto-dismiss) */
.toast {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 400;
    max-width: 360px;
    padding: 12px 16px;
    background: var(--text);
    color: #fff;
    border-radius: var(--radius);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.08);
    font-size: 13px;
    line-height: 1.5;
    opacity: 0;
    transform: translateY(12px);
    pointer-events: none;
    transition: opacity 0.22s ease-out, transform 0.22s ease-out;
}

.toast.toast--open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}

.toast.toast--welcome {
    background: #1a1a1a;
}

@media (max-width: 768px) {
    .toast {
        left: 12px;
        right: 12px;
        max-width: none;
    }
}

/* Responsive */
@media (max-width: 768px) {
    .sidebar {
        position: fixed;
        top: var(--header-height);
        left: 0;
        right: 0;
        bottom: 0;
        /* !important beats the inline style.width / style.minWidth that the
           desktop resizer writes (and persists to localStorage). On mobile
           the saved width preference is irrelevant — the sidebar always
           fills the viewport. */
        width: auto !important;
        min-width: 0 !important;
        /* Drop the 1px right border. With box-sizing: border-box the border
           eats into the sidebar's content area, so child panes at width:100%
           render 1px short of the sidebar's outer edge — the visible 1px
           gap. The border has no purpose on mobile anyway since the sidebar
           is a fullscreen overlay (no editor showing alongside). */
        border-right: 0;
        z-index: 50;
        box-shadow: 2px 0 12px rgba(0, 0, 0, 0.08);
    }

    .sidebar.hidden {
        margin-left: -100vw;
    }

    /* Mobile shows ONE pane at a time. Each pane fills the viewport; the
       active class on .sidebar decides which is visible. JS toggles
       .sidebar--folders / .sidebar--notes (and folds back to folders via
       the back button in .notesPaneHeader). Same !important trick as
       above — the folders-pane resizer also writes inline widths. */
    .foldersPane,
    .notesPane {
        width: 100% !important;
        min-width: 0 !important;
        flex-shrink: 0;
    }
    .sidebar--folders .notesPane { display: none; }
    .sidebar--notes   .foldersPane { display: none; }

    /* Back button in the notes pane is the one-tap return to the folder
       list — only meaningful on mobile, hidden on desktop. */
    .notesPaneBack { display: inline-flex; }

    /* The pane toggles let the user dismiss the sidebar overlay from inside
       it (the editor toolbar's toggle is hidden behind the sidebar on
       mobile, so we need a reachable handle here). */
    .sidebarPaneToggle { display: inline-flex; }

    /* Resizers are a desktop affordance only — pointer-action on mobile
       would be confusing and there's nothing to resize when one pane fills
       the full viewport width. */
    .sidebarResizer,
    .foldersPaneResizer { display: none; }

    /* Folder action overflow + count are now always visible on every
       viewport — the desktop rules above already keep .folderItemActions
       displayed and don't toggle .folderItemCount, so no mobile override
       is needed here. */

    /* Per-note action affordances (folder picker + delete) hide-on-hover
       doesn't work without a pointer — keep them visible on mobile so the
       user can actually reach them. */
    .noteItemFolder,
    .noteItemDelete {
        opacity: 1;
    }

    /* Native iOS HIG = 44pt minimum touch target. Bump every icon button
       inside the sidebar/list surface to 40px (in-row) or 44px (standalone)
       so taps feel deliberate instead of fiddly. */
    .sidebarSortBtn {
        width: 40px;
        height: 40px;
        font-size: 16px;
    }

    /* Sidebar pane header grows to 56px to accommodate the larger 40px
       buttons with breathing room (8px each side). The editor toolbar
       gets the same treatment in editor.css so the toggle stays in
       pixel-perfect alignment when the sidebar overlay opens. */
    .notesPaneHeader {
        height: 56px;
    }
    .notesPaneBack {
        width: 40px;
        height: 40px;
        font-size: 16px;
    }
    /* Mobile: keep the label visible — markup reads "Notes" by default
       and is swapped to the active folder name by the JS in
       index.php — so the toggle reads as "tap to open <pane>". */
    .sidebarPaneToggle {
        height: 40px;
        padding: 0 12px;
        font-size: 14px;
    }
    .sidebarPaneToggle .fa-table-columns { font-size: 16px; }
    .notesPaneNewBtn {
        min-height: 40px;
        min-width: 40px;
    }
    .notesPaneNewBtn:not(:has(.notesPaneNewBtnLabel)) {
        width: 40px;
    }

    /* Note-row kebab — was 28px which felt cramped under a thumb. */
    .noteItemActions {
        width: 40px;
        height: 40px;
        font-size: 16px;
        top: 0;
    }

    /* Bump sidebar text up a notch on mobile — the desktop sizes (11–13.5px)
       are uncomfortably small under a thumb. Search input is intentionally
       left alone since it already feels right at its current size. */
    .notesPaneTitle {
        font-size: 15px;
    }

    .notesPaneNewBtnLabel {
        font-size: 13.5px;
    }

    .folderItem {
        font-size: 15px;
        min-height: 36px;
    }

    .folderItemCount {
        font-size: 12.5px;
    }

    .noteItem {
        padding: 12px;
    }

    .noteItemTitle {
        font-size: 15.5px;
    }

    .noteItemPreview {
        font-size: 13px;
    }

    .noteItemDate {
        font-size: 12px;
    }

    /* Folder kebab-overflow menu — desktop sizing (200px wide, 13px text,
       8/10 padding) feels cramped on mobile and the hover/focus bg flash
       lingers awkwardly after a tap on touch devices. Bump dimensions and
       drop the hover/focus background fill. */
    .folderActionsMenu {
        min-width: 240px;
        padding: 8px;
    }

    .folderActionsItem {
        gap: 14px;
        padding: 14px 14px;
        font-size: 16px;
    }

    .folderActionsItem i {
        width: 20px;
        font-size: 16px;
    }

    .folderActionsItem:hover,
    .folderActionsItem:focus,
    .folderActionsItem:focus-visible {
        background: transparent;
    }
    .folderActionsItem--danger:hover,
    .folderActionsItem--danger:focus,
    .folderActionsItem--danger:focus-visible {
        background: transparent;
    }

    .folderActionsDivider {
        margin: 6px 8px;
    }
}

/* First-visit onboarding modal — iOS-style centered welcome card. */
.onboardingModalContent {
    width: 380px;
    max-width: calc(100% - 32px);
    padding: 32px 28px 24px;
    text-align: center;
    border-radius: 18px;
    /* Cap height to viewport with breathing room so the Continue button is
       always reachable. Internal scroll handles overflow when the device is
       short (iPhone SE, on-screen keyboard, landscape, etc.). */
    max-height: calc(100vh - 32px);
    max-height: calc(100dvh - 32px); /* dvh accounts for mobile address bars */
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.onboardingHero {
    margin-bottom: 24px;
}

.onboardingAppIcon {
    width: 72px;
    height: 72px;
    margin: 0 auto 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #2D2D2D 0%, #4A4A4A 100%);
    color: #fff;
    border-radius: 18px;
    font-size: 30px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18), 0 1px 2px rgba(0, 0, 0, 0.06);
}

.onboardingTitle {
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin: 0 0 6px;
    color: var(--text);
}

.onboardingSubtitle {
    font-size: 13.5px;
    color: var(--text-secondary);
    line-height: 1.4;
    margin: 0;
}

.onboardingFeatures {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin: 0 0 24px;
    padding: 0;
    list-style: none;
    text-align: left;
}

.onboardingFeature {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.onboardingFeatureIcon {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    margin-top: 2px;
}

.onboardingFeatureIcon--pink   { color: #e84c6b; }
.onboardingFeatureIcon--green  { color: #2d9b5a; }
.onboardingFeatureIcon--purple { color: #7758c4; }
.onboardingFeatureIcon--blue   { color: #2563eb; }

.onboardingFeatureBody {
    flex: 1;
    min-width: 0;
}

.onboardingFeatureTitle {
    font-size: 14.5px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 2px;
    letter-spacing: -0.01em;
}

.onboardingFeatureDesc {
    font-size: 12.5px;
    color: var(--text-secondary);
    line-height: 1.45;
}

.onboardingContinueBtn {
    width: 100%;
    padding: 12px 14px;
    font-size: 14px;
    font-weight: 600;
    border-radius: var(--radius);
}

/* Mobile: tighter vertical rhythm + smaller hero so the whole card has a
   better chance of fitting above the fold. Continue button becomes sticky
   to the bottom of the scrollable card so it's always one tap away. */
@media (max-width: 600px), (max-height: 700px) {
    .onboardingModalContent {
        padding: 22px 20px 16px;
        max-width: calc(100% - 24px);
        max-height: calc(100vh - 16px);
        max-height: calc(100dvh - 16px);
    }
    .onboardingHero {
        margin-bottom: 16px;
    }
    .onboardingAppIcon {
        width: 56px;
        height: 56px;
        margin-bottom: 12px;
        font-size: 24px;
        border-radius: 14px;
    }
    .onboardingTitle {
        font-size: 20px;
    }
    .onboardingSubtitle {
        font-size: 13px;
    }
    .onboardingFeatures {
        gap: 12px;
        margin-bottom: 16px;
    }
    .onboardingFeatureIcon {
        width: 28px;
        height: 28px;
        font-size: 18px;
    }
    .onboardingFeatureTitle { font-size: 14px; }
    .onboardingFeatureDesc  { font-size: 12px; }
    .onboardingContinueBtn {
        position: sticky;
        bottom: 0;
        /* Soft cream halo above the sticky button so list content scrolling
           underneath fades out before it meets the CTA. The button keeps its
           primary dark fill from .confirmModalBtnPrimary — earlier this rule
           also set `background: var(--bg)`, which made the button render
           white-on-cream and effectively invisible on mobile. */
        box-shadow: 0 -16px 16px -8px var(--bg);
    }
}
