:root { color-scheme: dark; }

/* ========================================
       LAZY PROMPTER APP v1.40 (P0 Fixes)
       Design System: Master v1.5
       ======================================== */

    :root {
      /* Backgrounds */
      --lp-bg-base: #1E1F20;
      --lp-bg-surface: #2C2E31;
      --lp-bg-elevated: #353639;
      --lp-bg-input: #18191B;
      
      /* Text */
      --lp-text-primary: #FFFFFF;
      --lp-text-secondary: #C8C9CA;
      /* 2026-09-05: #8D8E90 was 3.68:1 on --lp-bg-elevated. Its replacement #9D9EA0 cleared
         base, surface and elevated and still missed the ground these labels are read on most:
         the ACTIVE spotlight row, --lp-wash-hover rgba(255,255,255,.04) over --lp-bg-surface,
         which composites to rgb(52.44,54.36,57.24). Measured 2026-09-21: 4.4952 there, printed
         as 4.50 and under the floor (SPOTLIGHT-TWO-SURFACES-2026-09-21 finding 6). #A0A1A3 is
         not a new value: it is what app_lazyprompter_admin and lazyprompter_seo already carry,
         so this closes the contrast miss and one drift in the shared vocabulary at once.
         4.6613 active / 4.6726 elevated / 5.2661 surface / 6.3846 base. */
      --lp-text-tertiary: #A0A1A3;
      
      /* Font Family */
      --lp-font-sans: Inter, system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
      --lp-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      
      /* Strokes */
      --lp-stroke-default: #3D3E40;
      --lp-stroke-light: #4B4C4F;
      --lp-stroke-strong: #5D5E60;
      
      /* Accent: the brand layer, not the system. Values live in design-system/brand/lazy-prompter/brand.json and ship as public/lp/lp-brand.css, loaded before this file. */

      /* Semantic */
      --lp-success: #7DFFD1;
      --lp-warning: #FFB65C;
      --lp-error: #FF6A6A;
      /* 2026-09-24: hover and active LIGHTEN in dark, like the rest of the dark theme; the old darker
         #D45555 / #B84545 held the dark label at 4.11:1 and 3.13:1, under AA. Now 6.80:1 and 7.79:1. */
      --lp-error-hover: #FF8080;
      --lp-error-active: #FF9494;
      --lp-text-on-error: #1E1F20; /* 5.91:1 on --lp-error */
      --lp-error-text: #FF6A6A; /* red TEXT on a surface; 2026-09-24: light #DC2626 measured 4.43:1 on --lp-bg-surface, under AA */
      --lp-success-text: var(--lp-success); /* TEXT-only status colours: on dark the fills already clear AA, the light theme is where they diverge */
      --lp-warning-text: var(--lp-warning);
      
      /* Tag Colors — Master v1.4 §9.2 (mapped to app's semantic names) */
      --lp-tag-rose: #E85A9C;    /* spec: pink */
      --lp-tag-amber: #C9A227;   /* spec: yellow */
      --lp-tag-lime: #3D9A6D;    /* spec: green */
      --lp-tag-cyan: #4A8FD4;    /* spec: blue */
      --lp-tag-violet: #9B6DC6;  /* spec: purple */
      --lp-tag-slate: #8D8E90;   /* neutral */
      
      /* Radius */
      --lp-radius-xs: 4px;
      --lp-radius-s: 8px;
      --lp-radius-m: 12px;
      --lp-radius-l: 16px;
      --lp-radius-xl: 20px;
      --lp-radius-full: 999px;
      
      /* Spacing */
      --lp-space-4: 4px;
      --lp-space-8: 8px;
      --lp-space-12: 12px;
      --lp-space-16: 16px;
      --lp-space-20: 20px;
      --lp-space-24: 24px;
      --lp-space-32: 32px;
      
      /* Typography */
      --lp-text-2xs: 10px;
      --lp-text-xs: 11px;
      --lp-text-sm: 12px;
      --lp-text-base: 13px;
      --lp-text-md: 14px;
      --lp-text-lg: 15px;
      --lp-text-lg-plus: 16px;
      --lp-text-xl: 18px;
      --lp-text-xl-plus: 20px;
      --lp-text-2xl: 24px;
      --lp-text-3xl: 28px;
      --lp-text-4xl: 32px; /* display: a marketing page title (lazyprompter.com), one size on every page (P12, 2026-09-24) */
      
      /* Font Weight */
      --lp-font-normal: 400;
      --lp-font-medium: 500;
      --lp-font-semibold: 600;
      
      /* Line Height */
      --lp-leading-none: 1;
      --lp-leading-tight: 1.3;
      --lp-leading-snug: 1.4;
      --lp-leading-normal: 1.5;
      --lp-leading-relaxed: 1.6;
      
      /* Letter Spacing */
      --lp-tracking-tight: -0.01em;
      --lp-tracking-normal: 0;
      --lp-tracking-wide: 0.05em;
      --lp-tracking-wider: 0.08em;
      
      /* Border Width */
      --lp-border-thin: 1px;
      --lp-border-thick: 2px;
      
      /* Icon Sizes */
      --lp-icon-sm: 14px;
      --lp-icon-base: 16px;
      --lp-icon-stroke: 1.75; /* 2026-09-24: what the shipped inline icons draw (Kenz, deviations.md decisions) */
      
      /* Component Heights */
      --lp-height-xs: 24px;
      --lp-height-sm: 32px;
      --lp-height-md: 40px;
      --lp-height-lg: 44px;
      --lp-height-xl: 56px;
      
      /* Size Scale (reusable) */
      --lp-size-2: 8px;
      --lp-size-4: 16px;
      --lp-size-5: 20px;
      --lp-size-6: 24px;
      --lp-size-8: 32px;
      --lp-size-10: 40px;
      
      /* Breakpoints (for reference, can't use in @media) */
      /* --lp-breakpoint-sm: 640px; */
      /* --lp-breakpoint-md: 768px; */
      /* --lp-breakpoint-lg: 992px; */
      /* --lp-breakpoint-xl: 1200px; */
      
      /* Shadows */
      --lp-shadow-s: 0 2px 6px rgba(0,0,0,0.35);
      --lp-shadow-m: 0 6px 18px rgba(0,0,0,0.40);
      --lp-shadow-l: 0 10px 28px rgba(0,0,0,0.40);
      
      /* Motion — Master v1.4 §9.7 */
      --lp-motion-instant: 0ms;
      --lp-motion-fast: 80ms;
      --lp-motion-mid: 120ms;
      --lp-motion-slow: 180ms;
      
      /* Animation Durations (looping/special) */
      --lp-anim-spin: 0.8s;
      --lp-anim-spin-fast: 0.6s;
      --lp-anim-skeleton: 2.2s;
      --lp-anim-pulse: 2s;
      
      /* Easing — Master v1.4 §9.7 */
      --lp-ease-out: cubic-bezier(0,0,0.2,1);
      
      /* Wash (rgba white overlays) — v1.36 */
      --lp-wash-subtle: rgba(255,255,255,0.03);
      --lp-wash-hover: rgba(255,255,255,0.04);
      --lp-wash-active: rgba(255,255,255,0.06);
      --lp-wash-strong: rgba(255,255,255,0.08);
      
      /* Mode Indicator Colors — v1.37 */
      --lp-mode-prompt: #4ADE80;
      --lp-mode-custom-ai: #60A5FA;
      
      /* Placeholder Surface — v1.36 */
      
      /* Unified Icon Opacity — v1.36 */
      --lp-icon-opacity: 0.85;
      
      /* State Opacity — v1.42 */
      --lp-opacity-disabled: 0.45;
      --lp-opacity-muted: 0.6;
      --lp-opacity-subtle: 0.5;
      --lp-opacity-locked: 0.4;
      --lp-opacity-loading: 0.7;
      
      /* Layout Dimensions — v1.37 */
      --lp-topbar-height: 56px;
      --lp-sidebar-width: 240px;
      --lp-sidebar-collapsed: 64px;
      --lp-content-max: 1040px;
      --lp-input-bar-max: 880px;
      --lp-bubble-max: 720px;
      --lp-bubble-user-max: 560px;
      --lp-modal-width: 560px;
      --lp-modal-lg: 680px;
      --lp-modal-min: 320px;
      
      /* Focus Ring Token — v1.36 */
      --lp-focus-ring: inset 0 0 0 1px var(--lp-accent-base);
      /* Rows consume a complete shadow, never prefix an inset token. */
      --lp-row-focus-ring: var(--lp-focus-ring);
      
      /* Z-Index Scale — v1.41 */
      --lp-z-dropdown: 10;
      --lp-z-sticky: 20;
      --lp-z-modal: 50;
      --lp-z-popover: 60;
      --lp-z-spotlight: 100;
      --lp-z-top: 200;
      
      /* Overlay Tokens — v1.41 */
      --lp-overlay-dark: rgba(0,0,0,0.55);
      --lp-overlay-darker: rgba(0,0,0,0.75);
      --lp-overlay-accent: color-mix(in srgb, var(--lp-accent-base) 15%, transparent);
      --lp-overlay-accent-strong: color-mix(in srgb, var(--lp-accent-base) 35%, transparent);
      --lp-overlay-accent-subtle: color-mix(in srgb, var(--lp-accent-base) 10%, transparent);
      --lp-overlay-error: rgba(255,106,106,0.1);
      --lp-overlay-muted: rgba(141,142,144,0.15);
      --lp-overlay-light-border: rgba(255,255,255,0.3);
      --lp-overlay-glass: rgba(30,31,32,0.8);
    }
    
    /* ========================================
       LIGHT THEME — v1.41
       ======================================== */
    
    [data-theme="light"] {
      /* Backgrounds */
      --lp-bg-base: #FFFFFF;
      --lp-bg-surface: #F5F5F5;
      --lp-bg-elevated: #EBEBEB;
      --lp-bg-input: #FFFFFF;
      
      /* Text */
      --lp-text-primary: #1A1A1A;
      --lp-text-secondary: #4A4A4A;
      /* 4.61:1 on --lp-bg-surface (#F5F5F5) and 5.02:1 on --lp-bg-base (#FFFFFF).
         The previous #757575 carried a comment claiming 4.6:1, which is true on WHITE
         and false on the surface these labels actually sit on: measured 4.23:1 there
         ("Signed in as ...", the plan tier, the spotlight empty state), under the 4.5
         floor for text this size. Darkened by the smallest step that clears both grounds.
         2026-09-06: #6F6F6F held on those two grounds and failed on the THIRD, the hover
         wash rgba(0,0,0,0.04) over --lp-bg-surface, which resolves to #EBEBEB and equals
         --lp-bg-elevated: measured 4.21:1 there (".spotlight-item__collection" on the
         active spotlight row). #6A6A6A is the smallest step clearing 4.5 on all three
         (5.41 / 4.96 / 4.54). Same shape as the dark-side fix at the top of this file. */
      --lp-text-tertiary: #6A6A6A;
      
      /* Strokes */
      --lp-stroke-default: #D4D4D4;
      --lp-stroke-light: #E5E5E5;
      --lp-stroke-strong: #BEBEBE;
      
      /* Accent: brand layer (public/lp/lp-brand.css). */
      
      /* Status */
      --lp-success: #059669;
      --lp-warning: #D97706;
      --lp-error: #DC2626;
      --lp-error-hover: #B91C1C;
      --lp-error-active: #991B1B;
      --lp-error-text: #B91C1C;
      --lp-success-text: #047857; /* green and amber as TEXT on light: the fills measure 3.46 and 2.92:1 there (2026-09-06, both panel demos) */
      --lp-warning-text: #B45309;
      --lp-text-on-error: #FFFFFF; /* 4.83 / 6.47 / 8.31:1 on error, hover, active; the dark label was 3.42:1 */
      
      /* Tags — aligned with dark theme names */
      --lp-tag-rose: #DB2777;
      --lp-tag-amber: #B45309;
      --lp-tag-lime: #059669;
      --lp-tag-cyan: #0284C7;
      --lp-tag-violet: #7C3AED;
      --lp-tag-slate: #6B7280;
      
      /* Wash (dark overlays on light bg) */
      --lp-wash-subtle: rgba(0,0,0,0.02);
      --lp-wash-hover: rgba(0,0,0,0.04);
      --lp-wash-active: rgba(0,0,0,0.06);
      --lp-wash-strong: rgba(0,0,0,0.08);
      
      /* Overlays */
      --lp-overlay-dark: rgba(0,0,0,0.4);
      --lp-overlay-darker: rgba(0,0,0,0.6);
      --lp-overlay-accent: color-mix(in srgb, var(--lp-accent-base) 10%, transparent);
      --lp-overlay-accent-strong: color-mix(in srgb, var(--lp-accent-base) 25%, transparent);
      --lp-overlay-accent-subtle: color-mix(in srgb, var(--lp-accent-base) 8%, transparent);
      --lp-overlay-error: rgba(220,38,38,0.1);
      --lp-overlay-muted: rgba(0,0,0,0.08);
      --lp-overlay-light-border: rgba(0,0,0,0.15);
      --lp-overlay-glass: rgba(255,255,255,0.85);
      
      /* Shadows (more visible on light) */
      --lp-shadow-s: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06);
      --lp-shadow-m: 0 4px 12px rgba(0,0,0,0.1), 0 2px 4px rgba(0,0,0,0.06);
      --lp-shadow-l: 0 12px 40px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08);
      
      /* Focus ring */
      --lp-focus-ring: 0 0 0 2px var(--lp-bg-base), 0 0 0 4px var(--lp-accent-base);
      /* Preserve the approved light row: inset ground gap, outward accent halo. */
      --lp-row-focus-ring: inset 0 0 0 2px var(--lp-bg-base), 0 0 0 4px var(--lp-accent-base);
    }
    
    /* ========================================
       ACCESSIBILITY & USER PREFERENCES
       ======================================== */
    
    /* Auto light theme when system prefers light (and no manual override) */
    /* Must mirror [data-theme="light"] exactly */
    @media (prefers-color-scheme: light) {
      :root:not([data-theme]) {
        /* Backgrounds */
        --lp-bg-base: #FFFFFF;
        --lp-bg-surface: #F5F5F5;
        --lp-bg-elevated: #EBEBEB;
        --lp-bg-input: #FFFFFF;
        /* Text */
        --lp-text-primary: #1A1A1A;
        --lp-text-secondary: #4A4A4A;
        --lp-text-tertiary: #6A6A6A; /* twin of the [data-theme="light"] value above */
        /* Strokes */
        --lp-stroke-default: #D4D4D4;
        --lp-stroke-light: #E5E5E5;
        --lp-stroke-strong: #BEBEBE;
        /* Accent: brand layer (public/lp/lp-brand.css). */
        /* Status */
        --lp-success: #059669;
        --lp-warning: #D97706;
        --lp-error: #DC2626;
        --lp-error-hover: #B91C1C;
        --lp-error-active: #991B1B;
        --lp-error-text: #B91C1C;
        --lp-success-text: #047857;
        --lp-warning-text: #B45309;
        --lp-text-on-error: #FFFFFF;
        /* Tags */
        --lp-tag-rose: #DB2777;
        --lp-tag-amber: #B45309;
        --lp-tag-lime: #059669;
        --lp-tag-cyan: #0284C7;
        --lp-tag-violet: #7C3AED;
        --lp-tag-slate: #6B7280;
        /* Wash */
        --lp-wash-subtle: rgba(0,0,0,0.02);
        --lp-wash-hover: rgba(0,0,0,0.04);
        --lp-wash-active: rgba(0,0,0,0.06);
        --lp-wash-strong: rgba(0,0,0,0.08);
        /* Overlays */
        --lp-overlay-dark: rgba(0,0,0,0.4);
        --lp-overlay-darker: rgba(0,0,0,0.6);
        --lp-overlay-accent: color-mix(in srgb, var(--lp-accent-base) 10%, transparent);
        --lp-overlay-accent-strong: color-mix(in srgb, var(--lp-accent-base) 25%, transparent);
        --lp-overlay-accent-subtle: color-mix(in srgb, var(--lp-accent-base) 8%, transparent);
        --lp-overlay-error: rgba(220,38,38,0.1);
        --lp-overlay-muted: rgba(0,0,0,0.08);
        --lp-overlay-light-border: rgba(0,0,0,0.15);
        --lp-overlay-glass: rgba(255,255,255,0.85);
        /* Shadows */
        --lp-shadow-s: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06);
        --lp-shadow-m: 0 4px 12px rgba(0,0,0,0.1), 0 2px 4px rgba(0,0,0,0.06);
        --lp-shadow-l: 0 12px 40px rgba(0,0,0,0.12), 0 4px 12px rgba(0,0,0,0.08);
        /* Focus ring */
        --lp-focus-ring: 0 0 0 2px var(--lp-bg-base), 0 0 0 4px var(--lp-accent-base);
      /* Preserve the approved light row: inset ground gap, outward accent halo. */
      --lp-row-focus-ring: inset 0 0 0 2px var(--lp-bg-base), 0 0 0 4px var(--lp-accent-base);
      }
    }
    
    /* Reduced motion: disable all animations */
    @media (prefers-reduced-motion: reduce) {
      :root:not([data-lp-reduce-motion="off"]) {
        --lp-motion-instant: 0ms;
        --lp-motion-fast: 0ms;
        --lp-motion-mid: 0ms;
        --lp-motion-slow: 0ms;
        --lp-anim-spin: 0.01ms;
        --lp-anim-spin-fast: 0.01ms;
        --lp-anim-skeleton: 0.01ms;
        --lp-anim-pulse: 0.01ms;
      }
      :root:not([data-lp-reduce-motion="off"]) *, :root:not([data-lp-reduce-motion="off"]) *::before, :root:not([data-lp-reduce-motion="off"]) *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
      }
    }
    
    /* High contrast mode (OS setting). Scoped per theme since 2026-09-05: the black-text block
       used to sit on a bare :root, so a dark-theme user with "increase contrast" on got
       #000000 on #1E1F20, 1.27:1, the worst pairing in the product. The light set below is the
       old block unchanged; the dark set mirrors body.high-contrast--dark further down. */
    @media (prefers-contrast: more) {
      [data-theme="light"]:not([data-lp-high-contrast="off"]) {
        --lp-text-primary: #000000;
        --lp-text-secondary: #1A1A1A;
        --lp-text-tertiary: #333333;
        --lp-stroke-default: #000000;
        --lp-stroke-light: #333333;
        --lp-stroke-strong: #000000;
        --lp-focus-ring: inset 0 0 0 3px #000000;
        --lp-row-focus-ring: var(--lp-focus-ring);
        --lp-bg-base: #FFFFFF;
        --lp-bg-surface: #F0F0F0;
      }
      [data-theme="dark"]:not([data-lp-high-contrast="off"]) {
        --lp-text-primary: #FFFFFF;
        --lp-text-secondary: #E0E0E0;
        --lp-text-tertiary: #C0C0C0;
        --lp-stroke-default: #666666;
        --lp-stroke-light: #555555;
        --lp-stroke-strong: #8A8A8A;
        --lp-focus-ring: inset 0 0 0 3px #FFFFFF;
        --lp-row-focus-ring: var(--lp-focus-ring);
      }
    }
    
    @media (prefers-contrast: more) and (prefers-color-scheme: light) {
      :root:not([data-theme]):not([data-lp-high-contrast="off"]) {
        --lp-text-primary: #000000;
        --lp-text-secondary: #1A1A1A;
        --lp-text-tertiary: #333333;
        --lp-stroke-default: #000000;
        --lp-stroke-light: #333333;
        --lp-stroke-strong: #000000;
        --lp-focus-ring: inset 0 0 0 3px #000000;
        --lp-row-focus-ring: var(--lp-focus-ring);
        --lp-bg-base: #FFFFFF;
        --lp-bg-surface: #F0F0F0;
      }
    }
    
    @media (prefers-contrast: more) and (prefers-color-scheme: dark) {
      :root:not([data-theme]):not([data-lp-high-contrast="off"]) {
        --lp-text-primary: #FFFFFF;
        --lp-text-secondary: #E0E0E0;
        --lp-text-tertiary: #C0C0C0;
        --lp-stroke-default: #666666;
        --lp-stroke-light: #555555;
        --lp-stroke-strong: #8A8A8A;
        --lp-focus-ring: inset 0 0 0 3px #FFFFFF;
        --lp-row-focus-ring: var(--lp-focus-ring);
      }
    }
    
    /* User preference: Reduced motion (via Settings) */
    body.reduced-motion {
      --lp-motion-instant: 0ms;
      --lp-motion-fast: 0ms;
      --lp-motion-mid: 0ms;
      --lp-motion-slow: 0ms;
    }
    
    body.reduced-motion *, 
    body.reduced-motion *::before, 
    body.reduced-motion *::after {
      animation-duration: 0.01ms !important;
      transition-duration: 0.01ms !important;
    }
    
    /* User preference: High contrast (via Settings) */
    /* Dark theme high contrast */
    body.high-contrast {
      --lp-stroke-default: #666666;
      --lp-stroke-light: #555555;
      --lp-border-thin: 2px;
    }
    
    body.high-contrast.high-contrast--dark {
      --lp-text-primary: #FFFFFF;
      --lp-text-secondary: #E0E0E0;
      --lp-text-tertiary: #C0C0C0;
    }
    
    body.high-contrast.high-contrast--light {
      --lp-text-primary: #000000;
      --lp-text-secondary: #1A1A1A;
      --lp-text-tertiary: #333333;
      --lp-stroke-default: #000000;
      --lp-stroke-light: #333333;
    }

    * { box-sizing: border-box; margin: 0; padding: 0; }
    
    /* ========================================
       UTILITY CLASSES — v1.41 (pruned: dead classes removed)
       ======================================== */
    
    /* Layout */
    .flex-1 { flex: 1; }
    
    /* Visibility */
    .hidden { display: none; }
    
    /* Screen reader only — visually hidden but accessible */
    .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;
    }
    
    html, body {
      height: 100%;
      height: 100dvh;
      overflow: hidden;
    }
    #app {
      /* The layout is a ROW: a sticky sidebar next to .main-shell, which is flex:1. All it ever
         lacked was a height to divide, so the flex:1 chain down to #session-content resolved to
         auto and the page scrolled instead of the stream (measured 2026-09-10: #app was 2,794px
         inside an 844px body and the composer sat 2,653px below the fold). A COLUMN here is wrong:
         it stacks the sidebar above the content at 1280 and pushes the composer off again. */
      height: 100%;
      display: flex;
      min-height: 0;
    }
    
    @supports not (height: 100dvh) {
      html, body {
        height: -webkit-fill-available;
      }
    }
    
    body {
      font-family: var(--lp-font-sans);
      background: var(--lp-bg-base);
      color: var(--lp-text-primary);
      -webkit-font-smoothing: antialiased;
      /* Safe area insets for iPhone notch/home indicator */
      padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    }
    
    ::selection {
      background: var(--lp-overlay-accent-strong);
      color: var(--lp-text-primary);
    }

    /* ========================================
       UTILITY CLASSES (R1 — replace top-duplicated inline style patterns)
       Note: .flex-1 + .hidden already exist in pre-existing utility block above,
             .stack-N is a semantic alias for .mt-N (same effect, more descriptive name)
       ======================================== */

    .row-between { display: flex; justify-content: space-between; align-items: center; }
    .row-gap-8 { display: flex; align-items: center; gap: var(--lp-space-8); }
    .row-gap-8-top { display: flex; gap: var(--lp-space-8); margin-top: var(--lp-space-8); }
    .stack-4 { margin-top: var(--lp-space-4); }
    .stack-8 { margin-top: var(--lp-space-8); }
    .stack-12 { margin-top: var(--lp-space-12); }
    .stack-16 { margin-top: var(--lp-space-16); }
    .stack-24 { margin-top: var(--lp-space-24); }
    .color-tertiary { color: var(--lp-text-tertiary); }
    .text-helper { font-size: var(--lp-text-xs); color: var(--lp-text-tertiary); }

    /* ========================================
       LAYOUT: APP SHELL
       ======================================== */
    
    .app {
      display: flex;
      height: 100vh;
      height: 100dvh; /* Dynamic viewport for mobile */
      overflow: hidden;
      background: var(--lp-bg-base);
    }
    
    /* iOS Safari fallback for dvh */
    @supports not (height: 100dvh) {
      .app {
        height: -webkit-fill-available;
      }
    }

    /* ========================================
       SIDEBAR
       ======================================== */
    
    .sidebar {
      position: sticky;
      top: 0;
      align-self: flex-start;
      height: 100vh;
      height: 100dvh;
      width: var(--lp-sidebar-width);
      background: var(--lp-bg-surface);
      padding: var(--lp-space-20) var(--lp-space-16);
      /* Safe area for notch in landscape */
      padding-left: max(var(--lp-space-16), env(safe-area-inset-left, 0px));
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-24);
      flex-shrink: 0;
      transition: width var(--lp-motion-mid) var(--lp-ease-out),
                  padding var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .sidebar__header {
      position: relative;
      display: flex;
      align-items: center;
    }
    
    .sidebar__header-left {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      overflow: hidden;
      transition: gap var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .sidebar__toggle {
      position: absolute;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
      width: var(--lp-size-6);
      height: var(--lp-size-6);
      border-radius: var(--lp-radius-xs);
      border: none;
      background: transparent;
      color: var(--lp-text-tertiary);
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      opacity: 0;
      z-index: var(--lp-z-dropdown);
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .sidebar:hover .sidebar__toggle,
    .sidebar:focus-within .sidebar__toggle {
      opacity: 1;
      transition: opacity var(--lp-motion-instant); /* instant on */
    }
    
    .sidebar__toggle:hover {
      background: var(--lp-wash-strong);
      color: var(--lp-text-secondary);
      transition: opacity var(--lp-motion-instant), background var(--lp-motion-instant), color var(--lp-motion-instant);
    }
    
    .sidebar--collapsed .sidebar__toggle .icon-expand {
      display: block;
    }
    
    .sidebar--collapsed .sidebar__toggle .icon-collapse {
      display: none;
    }
    
    .sidebar__toggle .icon-expand {
      display: none;
    }
    
    .sidebar__toggle .icon-collapse {
      display: block;
    }
    
    .logo-mark {
      width: 24px;
      height: 24px;
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .logo-mark svg {
      width: 100%;
      height: 100%;
    }
    
    .logo-text {
      font-size: var(--lp-text-base);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-secondary);
      white-space: nowrap;
      overflow: hidden;
      transition: width var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .sidebar__section {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
    }
    
    .sidebar__section--footer {
      margin-top: auto;
    }
    
    .sidebar__section-title {
      font-size: var(--lp-text-xs);
      font-weight: var(--lp-font-semibold);
      text-transform: uppercase;
      letter-spacing: var(--lp-tracking-wider);
      color: var(--lp-text-secondary);
      padding: var(--lp-space-4) var(--lp-space-8);
      white-space: nowrap;
      overflow: hidden;
      transition: height var(--lp-motion-mid) var(--lp-ease-out),
                  padding var(--lp-motion-mid) var(--lp-ease-out),
                  margin var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .nav-group {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
    }
    
    .nav-item {
      position: relative;
      height: 36px;
      padding: 0 var(--lp-space-12) 0 var(--lp-space-16);
      border-radius: var(--lp-radius-s);
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      user-select: none;
      overflow: hidden;
      transition: background var(--lp-motion-mid) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out),
                  gap var(--lp-motion-mid) var(--lp-ease-out),
                  padding var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .nav-item__content {
      display: flex;
      align-items: center;
      flex: 1;
      min-width: 0;
      gap: var(--lp-space-8);
      white-space: nowrap;
      overflow: hidden;
      /* Text appears/disappears instantly - width handles smooth transition */
      transition: width var(--lp-motion-mid) var(--lp-ease-out),
                  flex var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .nav-item__icon {
      width: var(--lp-icon-base);
      height: var(--lp-icon-base);
      flex-shrink: 0;
      opacity: var(--lp-icon-opacity);
    }
    
    /* SVG Icons */
    .icon {
      width: var(--lp-icon-base);
      height: var(--lp-icon-base);
      fill: none;
      stroke: currentColor;
      stroke-width: var(--lp-icon-stroke);
      stroke-linecap: round;
      stroke-linejoin: round;
    }
    
    .icon--sm { width: var(--lp-icon-sm); height: var(--lp-icon-sm); }
    .icon--lg { width: var(--lp-size-5); height: var(--lp-size-5); }
    
    .nav-item:hover {
      background: var(--lp-wash-subtle);
      color: var(--lp-text-primary);
      transition: background var(--lp-motion-instant), color var(--lp-motion-instant);
    }
    
    .nav-item:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }
    
    .nav-item--active {
      background: var(--lp-wash-hover);
      color: var(--lp-text-primary);
    }
    
    .nav-item--active::before {
      content: "";
      position: absolute;
      left: 0;
      top: var(--lp-space-8);
      bottom: var(--lp-space-8);
      width: 2px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
    }
    
    /* Locked nav items (Free user) */
    .nav-item--locked {
      opacity: var(--lp-opacity-locked);
      cursor: not-allowed;
    }
    .nav-item--locked:hover {
      background: transparent;
    }
    
    .badge-pro {
      margin-left: auto;
      padding: 0 var(--lp-space-8);
      height: var(--lp-size-4);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      font-size: var(--lp-text-2xs);
      font-weight: var(--lp-font-medium);
      display: flex;
      align-items: center;
      justify-content: center;
      letter-spacing: var(--lp-tracking-wide);
      color: var(--lp-text-secondary);
      white-space: nowrap;
      overflow: hidden;
    }
    
    /* Collapsed sidebar */
    .sidebar--collapsed {
      width: 72px;
      padding-inline: 0;
    }
    
    .sidebar--collapsed .sidebar__header {
      padding: 0;
      justify-content: center;
    }
    
    .sidebar--collapsed .sidebar__header-left {
      justify-content: center;
      gap: 0;
    }
    
    .sidebar--collapsed .logo-text {
      width: 0;
      overflow: hidden;
      pointer-events: none;
    }
    
    .sidebar--collapsed .sidebar__section-title {
      height: 0;
      padding: 0;
      margin: 0;
      overflow: hidden;
      pointer-events: none;
    }
    
    .sidebar--collapsed .nav-item__content {
      width: 0;
      flex: 0;
      overflow: hidden;
      pointer-events: none;
    }
    
    .sidebar--collapsed .nav-item {
      justify-content: center;
      padding: 0 var(--lp-space-12);
      gap: 0;
    }
    
    /* Mobile sidebar */
    .sidebar-overlay {
      position: fixed;
      inset: 0;
      background: var(--lp-overlay-dark);
      z-index: var(--lp-z-sticky);
      opacity: 0;
      pointer-events: none;
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .sidebar-overlay--visible {
      opacity: 1;
      pointer-events: auto;
    }
    
    /* Mobile popover overlay (for bottom sheet popovers) */
    .popover-overlay {
      position: fixed;
      inset: 0;
      background: var(--lp-overlay-dark);
      z-index: calc(var(--lp-z-popover) - 1);
      opacity: 0;
      pointer-events: none;
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .popover-overlay--visible {
      opacity: 1;
      pointer-events: auto;
    }

    /* ========================================
       MAIN SHELL + TOPBAR
       ======================================== */
    
    .main-shell {
      flex: 1;
      display: flex;
      flex-direction: column;
      min-width: 0;
      overflow: hidden;
      background: var(--lp-bg-base);
    }

    /* v2.7 (T5): dismissable notice for ?from=restricted-page redirects */
    .restricted-banner {
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      margin: var(--lp-space-12) var(--lp-space-16) 0;
      padding: var(--lp-space-8) var(--lp-space-16);
      background: var(--lp-bg-elevated);
      border: 1px solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-s);
      color: var(--lp-text-secondary);
      font-size: var(--lp-text-sm);
    }
    /* the × is THE close control (.pe__iconbtn); this only keeps it from shrinking */
    .restricted-banner__close { flex-shrink: 0; }

    .topbar {
      z-index: var(--lp-z-dropdown);
      height: var(--lp-topbar-height);
      padding: 0 var(--lp-space-20);
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-16);
      background: var(--lp-bg-base);
      flex-shrink: 0;
    }
    
    .topbar__left,
    .topbar__right {
      display: flex;
      align-items: center;
      gap: var(--lp-space-12);
    }
    
    .topbar__right {
      margin-left: auto;
    }
    
    .topbar__left {
      display: none;
      gap: var(--lp-space-8);
      margin-right: auto;
    }
    
    /* Mobile toggle hidden by default */
    .topbar__toggle-mobile {
      display: none;
    }
    
    .icon-btn {
      position: relative;
      width: var(--lp-size-8);
      height: var(--lp-height-sm);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thin) solid transparent;
      background: transparent;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--lp-text-tertiary);
      transition: border-color var(--lp-motion-mid) var(--lp-ease-out),
                  background var(--lp-motion-mid) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .icon-btn .icon {
      width: var(--lp-icon-sm);
      height: var(--lp-icon-sm);
    }
    
    .icon-btn:hover {
      border-color: var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      color: var(--lp-text-primary);
      transition: border-color var(--lp-motion-instant), background var(--lp-motion-instant), color var(--lp-motion-instant);
    }
    
    .search-trigger {
      width: 220px;
      height: 36px;
      border-radius: var(--lp-radius-s);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      padding: 0 var(--lp-space-12);
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      transition: border-color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .search-trigger:hover {
      border-color: var(--lp-stroke-light);
      transition: border-color var(--lp-motion-instant);
    }
    
    .search-trigger .icon {
      flex-shrink: 0;
      opacity: var(--lp-icon-opacity);
    }
    
    .search-trigger__kbd {
      margin-left: auto;
      padding: var(--lp-space-4) var(--lp-space-8);
      border-radius: var(--lp-radius-s);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      font-size: var(--lp-text-xs);
      color: var(--lp-text-secondary);
    }

    /* ========================================
       PAGE CONTENT
       ======================================== */
    
    .page {
      flex: 1;
      display: none;
      min-height: 0;
    }
    
    .page--active {
      display: flex;
      flex-direction: column;
      overflow-y: auto;
      overflow-x: hidden;
      /* Prevent layout shift when scrollbar appears/disappears */
      scrollbar-gutter: stable;
    }
    
    /* Safari fallback for scrollbar-gutter */
    @supports not (scrollbar-gutter: stable) {
      .page--active {
        overflow-y: scroll;
      }
    }
    
    /* Session page: input bar fixed at bottom, content scrolls */
    .page[data-page="session"].page--active {
      overflow: hidden;
    }
    
    .page[data-page="session"] .page-inner {
      min-height: 0;
      height: 100%;
      overflow: hidden;
    }
    
    .page-inner {
      min-height: calc(100vh - var(--lp-topbar-height, 56px));
      min-height: calc(100dvh - var(--lp-topbar-height, 56px));
      width: 100%;
      max-width: var(--lp-content-max, 1040px);
      margin: 0 auto;
      padding: var(--lp-space-24);
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-20);
    }
    
    .content-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: var(--lp-space-12);
      flex-wrap: wrap;
    }
    
    .content-header__title {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
    }
    
    .content-title {
      font-size: var(--lp-text-xl);
      font-weight: var(--lp-font-semibold);
    }
    
    .content-sub {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
    }

    /* ========================================
       BUTTONS
       ======================================== */
    
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: var(--lp-space-8);
      padding: 0 var(--lp-space-16);
      min-width: var(--lp-sidebar-collapsed);
      height: var(--lp-height-sm);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thin) solid transparent;
      cursor: pointer;
      font-size: var(--lp-text-base);
      font-weight: var(--lp-font-medium);
      background: transparent;
      color: var(--lp-text-secondary);
      transition: background var(--lp-motion-mid) var(--lp-ease-out),
                  border-color var(--lp-motion-mid) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .btn:hover {
      transition-duration: var(--lp-motion-instant);
    }
    
    .btn--primary {
      background: var(--lp-accent-base);
      border-color: var(--lp-accent-base);
      color: var(--lp-text-on-accent);
    }
    
    .btn--primary:hover {
      background: var(--lp-accent-hover);
      border-color: var(--lp-accent-hover);
    }
    
    .btn--primary:active {
      background: var(--lp-accent-active);
      border-color: var(--lp-accent-active);
      transform: scale(0.97);
    }
    
    .btn--outline {
      background: transparent;
      border-color: var(--lp-stroke-default);
      color: var(--lp-text-secondary);
    }
    
    .btn--outline:hover {
      border-color: var(--lp-stroke-light);
      color: var(--lp-text-primary);
    }
    
    .btn--sm {
      height: var(--lp-height-xs);
      padding-inline: var(--lp-space-12);
      font-size: var(--lp-text-xs);
      min-width: auto;
    }
    
    /* min-height 24 (2026-09-25): with height auto a tertiary button was its line of text, 17 tall ("Not now" on Apps,
       "Show guide" on Earn, "Download" in Billing), under the 24 by 24 floor of WCAG 2.5.8 with a pointer. */
    .btn--tertiary {
      background: none;
      border-color: transparent;
      color: var(--lp-text-secondary);
      padding-inline: 0;
      min-width: auto;
      height: auto;
      min-height: var(--lp-size-6);
    }
    
    .btn--tertiary:hover {
      color: var(--lp-text-primary);
    }
    
    /* The Earn calculator's quick-set row ("5", "10", "20") is the one place a tertiary
       button carries a one- or two-character label. With padding-inline: 0 above, those
       measured 9x44 and 16x44 at 390x844: tall enough, far too narrow to hit. Scoped to
       that row so the long tertiary labels elsewhere ("Copy lifetime link") keep reading
       as links rather than gaining padding they do not need. */
    .row-gap-8-top > .btn--tertiary {
      min-width: 44px;
      min-height: 44px;
    }
    
    /* Danger variant for destructive actions */
    .btn--primary.btn--danger {
      background: var(--lp-error);
      border-color: var(--lp-error);
      color: var(--lp-text-on-error);
    }
    
    .btn--primary.btn--danger:hover {
      background: var(--lp-error-hover);
      border-color: var(--lp-error-hover);
    }
    
    .btn--primary.btn--danger:active {
      background: var(--lp-error-active);
      border-color: var(--lp-error-active);
    }
    
    .btn:disabled {
      opacity: var(--lp-opacity-disabled);
      cursor: default;
    }
    
    .btn:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }
    
    .icon-btn:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }

    /* ========================================
       INPUTS
       ======================================== */
    
    .input {
      font-family: inherit;
      font-size: var(--lp-text-base);
      font-size: max(16px, var(--lp-text-base)); /* Prevent iOS zoom */
      color: var(--lp-text-primary);
      background: var(--lp-bg-input);
      border-radius: var(--lp-radius-s);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      height: var(--lp-height-lg);
      padding: 0 var(--lp-space-12);
      width: 100%;
    }
    
    .input::placeholder {
      color: var(--lp-text-tertiary);
    }
    
    .input:focus {
      outline: none;
      border-color: transparent;
      box-shadow: var(--lp-focus-ring);
    }
    
    .textarea {
      width: 100%;
      font-family: inherit;
      font-size: var(--lp-text-base);
      font-size: max(16px, var(--lp-text-base)); /* Prevent iOS zoom */
      color: var(--lp-text-primary);
      background: var(--lp-bg-input);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      padding: var(--lp-space-12) var(--lp-space-16);
      min-height: 220px;
      resize: vertical;
    }
    
    .textarea::placeholder {
      color: var(--lp-text-tertiary);
    }
    
    .textarea:focus {
      outline: none;
      border-color: transparent;
      box-shadow: var(--lp-focus-ring);
    }
    
    textarea.input {
      height: auto;
      padding: var(--lp-space-12);
      resize: vertical;
    }
    
    /* Password input wrapper with eye toggle */
    .input--password {
      position: relative;
    }
    .input--password > .input {
      padding-right: 40px;
    }
    /* Hide browser-native password reveal button (Edge ::-ms-reveal, some Chromium variants) */
    .input--password > .input[type="password"]::-ms-reveal,
    .input--password > .input[type="password"]::-ms-clear,
    .input--password > .input[type="password"]::-webkit-contacts-auto-fill-button,
    .input--password > .input[type="password"]::-webkit-credentials-auto-fill-button,
    .input--password > .input[type="text"]::-ms-reveal,
    .input--password > .input[type="text"]::-ms-clear {
      display: none !important;
      visibility: hidden !important;
      pointer-events: none !important;
      position: absolute !important;
      right: 0 !important;
    }
    .password-toggle-btn {
      position: absolute;
      right: 8px;
      top: 50%;
      transform: translateY(-50%);
      width: 28px;
      height: 28px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      background: transparent;
      border: 0;
      border-radius: var(--lp-radius-s);
      color: var(--lp-text-tertiary);
      cursor: pointer;
      padding: 0;
    }
    .password-toggle-btn:hover {
      color: var(--lp-text-secondary);
      background: var(--lp-bg-elevated);
    }
    .password-toggle-btn:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }
    .password-toggle-btn svg {
      width: var(--lp-icon-base);
      height: var(--lp-icon-base);
    }
    .password-toggle-btn .icon-eye-off {
      display: none;
    }
    .password-toggle-btn[data-shown="true"] .icon-eye {
      display: none;
    }
    .password-toggle-btn[data-shown="true"] .icon-eye-off {
      display: inline-block;
    }
    

    /* ========================================
       FILTERS
       ======================================== */
    
    .filter-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      flex-wrap: wrap;
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
    }
    
    .filter-tabs {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      flex-wrap: nowrap;
      overflow-x: auto;
      padding-bottom: var(--lp-space-4);
      /* Allow overflow to work in flex container */
      min-width: 0;
      flex: 1;
      /* Smooth scroll on touch */
      -webkit-overflow-scrolling: touch;
      scroll-behavior: smooth;    }
        
    .filter-chip {
      border: none;
      background: transparent;
      padding: var(--lp-space-8) 0;
      margin-right: var(--lp-space-12);
      /* A finger, not a cursor, presses these. Measured at 390x844 they came out
         14x33 ("All" on History) and 29x33 ("All 0" on Collections): both axes under
         the 44px floor, on the control that decides what the whole list shows.
         min-* only ever grows a chip that is already too small, so the wider chips
         on the same row keep the size they had. */
      display: inline-flex;
      align-items: center;
      justify-content: center;
      min-height: 44px;
      min-width: 44px;
      /* 06/09: the block above made these flex items inside .filter-tabs without
         telling them not to shrink. Flex items shrink by default, so each chip's
         BOX collapsed toward 44px while `white-space: nowrap` kept its TEXT at full
         width, and the overflow painted straight over the Organize / Tidy up buttons
         beside it. .filter-tabs already scrolls (overflow-x: auto); it could not do
         its job while the chips were still agreeing to shrink. */
      flex-shrink: 0;
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      white-space: nowrap;
      border-bottom: 2px solid transparent;
      transition: color var(--lp-motion-mid) var(--lp-ease-out),
                  border-color var(--lp-motion-mid) var(--lp-ease-out),
                  opacity var(--lp-motion-fast) var(--lp-ease-out),
                  transform var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .filter-chip:hover {
      color: var(--lp-text-primary);
      transition: color var(--lp-motion-instant);
    }
    
    .filter-chip--active {
      color: var(--lp-text-primary);
      border-color: var(--lp-accent-base);
    }
    
    .filter-chip:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
      border-radius: var(--lp-radius-xs);
    }
    
    /* Filter chip drag & drop */
    .filter-chip--dragging {
      opacity: var(--lp-opacity-subtle);
      transform: scale(0.95);
    }
    
    .filter-chip--drop-target {
      border-color: var(--lp-accent-base);
    }
    
    /* Fixed tabs (All, Pinned) - not draggable */
    .filter-chip--fixed {
      cursor: pointer;
    }
    
    .filter-chip[draggable="true"] {
      cursor: grab;
    }
    
    .filter-chip[draggable="true"]:active {
      cursor: grabbing;
    }
    

    /* ========================================
       COLLECTIONS GRID + CARDS
       ======================================== */
    
    .collections-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
      gap: var(--lp-space-20);
    }
    
    .card {
      background: var(--lp-bg-surface);
      border-radius: var(--lp-radius-m);
      padding: var(--lp-space-16);
      border: var(--lp-border-thin) solid transparent;
      box-shadow: var(--lp-shadow-s);
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      min-height: 120px;
      max-width: 320px;
      cursor: pointer;
      transition: box-shadow var(--lp-motion-mid) var(--lp-ease-out),
                  border-color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .card:hover {
      border-color: var(--lp-stroke-light);
      box-shadow: var(--lp-shadow-m);
      transition: box-shadow var(--lp-motion-instant), border-color var(--lp-motion-instant);
    }
    
    .card:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring), var(--lp-shadow-m);
    }
    
    /* Row 1: title + pin + hover actions. Title-first per GS9 progressive disclosure. */
    .card__top {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      min-width: 0;
    }

    .card__title {
      font-size: var(--lp-text-lg);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      line-height: var(--lp-leading-tight);
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .card__pin {
      width: 6px;
      height: 6px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
      flex-shrink: 0;
    }

    .card__actions {
      margin-left: auto;
      display: inline-flex;
      align-items: center;
      gap: var(--lp-space-4);
      opacity: 0;
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out);
    }

    .card:hover .card__actions,
    .card:focus-within .card__actions {
      opacity: 1;
      transition: opacity var(--lp-motion-instant);
    }

    /* Icon-btn shared base — card actions + spotlight QA (R4 dedup) */
    .card__action-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 24px;
      height: 24px;
      border: none;
      background: none;
      padding: 0;
      color: var(--lp-text-tertiary);
      cursor: pointer;
      border-radius: var(--lp-radius-s);
      transition: color var(--lp-motion-fast) var(--lp-ease-out),
                  background var(--lp-motion-fast) var(--lp-ease-out);
    }

    .card__action-btn:hover {
      color: var(--lp-text-primary);
      background: var(--lp-wash-hover);
    }

    .card__action-btn:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }

    /* Row 2: preview (hero content), sm text — shared by card + spotlight (R2 dedup) */
    .card__preview {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
      line-height: var(--lp-leading-snug);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    /* Row 3: subordinate meta (collection › tag · time) — shared by card + spotlight (R2 dedup) */
    .card__meta {
      display: flex;
      align-items: center;
      gap: var(--lp-space-4);
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
      line-height: var(--lp-leading-none);
    }
    /* Card-only: push meta to bottom of the flex-column card */
    .card__meta {
      margin-top: auto;
    }

    /* Collection link — shared by card + spotlight (R2 dedup) */
    .card__collection {
      cursor: pointer;
      transition: color var(--lp-motion-fast) var(--lp-ease-out);
    }
    .card__collection:hover {
      color: var(--lp-text-secondary);
      text-decoration: underline;
    }
    /* Card-only: clamp width since card is narrow */
    .card__collection {
      white-space: nowrap;
      max-width: 100px;
      overflow: hidden;
      text-overflow: ellipsis;
    }

    /* Meta separator tokens (chevron + dot) — shared by card + spotlight (R2 dedup) */
    .card__meta-sep,
    .card__meta-dot {
      color: var(--lp-text-tertiary);
      flex-shrink: 0;
    }

    /* Time separator (dot between tag and time). Separate class so the
       show-collection toggle below does not hide the tag-time dot. */
    /* .card__meta-dot styled in compound rule above */

    .card__last-used {
      color: var(--lp-text-tertiary);
      flex-shrink: 0;
      white-space: nowrap;
    }

    /* Tag base — font-weight shared by card + spotlight (R2 dedup) */
    .card__tag {
      font-weight: var(--lp-font-medium);
    }
    /* Card-only: clamp tag width + shrink behavior (card is narrow) */
    .card__tag {
      flex-shrink: 0;
      white-space: nowrap;
      max-width: 120px;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    /* Tag colors — shared between card + spotlight row (R2 dedup) */
    .card__tag--rose { color: var(--lp-tag-rose); }
    .card__tag--amber { color: var(--lp-tag-amber); }
    .card__tag--lime { color: var(--lp-tag-lime); }
    .card__tag--cyan { color: var(--lp-tag-cyan); }
    .card__tag--violet { color: var(--lp-tag-violet); }
    .card__tag--slate { color: var(--lp-tag-slate); }

    /* Collection label + its chevron separator: hidden by default,
       shown via grid class when viewing "All" across collections. */
    .card__collection,
    .card__meta-sep { display: none; }
    .collections-grid.show-collection .card__collection,
    .collections-grid.show-collection .card__meta-sep { display: inline; }

    .filter-chip__count {
      margin-left: var(--lp-space-4);
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
      font-weight: var(--lp-font-normal);
      font-variant-numeric: tabular-nums;
    }
    
    /* A text button is at least 24 tall with a pointer (WCAG 2.5.8; Copy and Save under a result measured 30x14). */
    .link-button {
      display: inline-flex;
      align-items: center;
      min-height: var(--lp-size-6);
      border: none;
      background: none;
      padding: 0;
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-tertiary);
      cursor: pointer;
      transition: color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .link-button:hover {
      color: var(--lp-text-primary);
      transition: color var(--lp-motion-instant);
    }
    
    .link-button:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
      border-radius: var(--lp-radius-xs);
    }
    
    .link-button--accent {
      color: var(--lp-text-secondary);
    }
    
    .link-button--accent:hover {
      color: var(--lp-text-primary);
      transition: color var(--lp-motion-instant);
    }
    
    .link-button--sm {
      font-size: var(--lp-text-xs);
    }
    
    .kebab-btn {
      width: var(--lp-size-5);
      height: var(--lp-size-5);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: transparent;
      cursor: pointer;
      font-size: var(--lp-text-sm);
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--lp-text-secondary);
      transition: border-color var(--lp-motion-fast) var(--lp-ease-out),
                  background var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .kebab-btn:hover {
      border-color: var(--lp-stroke-light);
      background: var(--lp-bg-elevated);
      color: var(--lp-text-primary);
      transition: all var(--lp-motion-instant);
    }

    /* ========================================
       POPOVERS — Master v1.4 §6.6, §6.7
       ======================================== */
    
    .popover {
      position: fixed;
      width: 360px;
      max-width: 96vw;
      max-height: 420px;
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-surface);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      box-shadow: var(--lp-shadow-m);
      overflow-y: auto;
      transform: translateY(8px);
      opacity: 0;
      pointer-events: none;
      transition: transform var(--lp-motion-fast) var(--lp-ease-out),
                  opacity var(--lp-motion-fast) var(--lp-ease-out);
      z-index: var(--lp-z-popover);
    }
    
    .popover--open {
      opacity: 1;
      pointer-events: auto;
      transform: translateY(0);
    }
    
    /* Popover width variants — Spec §9.8 */
    #notifications-popover { 
      width: 360px;
      display: flex;
      flex-direction: column;
    }
    #notifications-popover .popover__header {
      flex-shrink: 0;
    }
    #notifications-list {
      flex: 1;
      min-height: 0;
      max-height: 320px;
      overflow-y: auto;
    }
    #account-popover { width: 280px; max-height: 340px; }
    #kebab-popover { width: 180px; }
    
    .popover__header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-8);
      margin-bottom: var(--lp-space-8);
    }
    
    .popover__header .popover__title {
      margin-bottom: 0;
    }
    
    .popover__title {
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-secondary);
      margin-bottom: var(--lp-space-12);
      padding-top: var(--lp-space-4);
    }
    
    .popover__item {
      height: var(--lp-height-sm);
      border-radius: var(--lp-radius-s);
      padding: 0 var(--lp-space-12);
      display: flex;
      align-items: center;
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      transition: background var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    button.popover__item, button.notif-item {
      width: 100%;
      border: 0;
      background: transparent;
      font: inherit;
      text-align: left;
    }
    /* 2026-09-24: `font: inherit` above resets the browser's button font and also took the size, so the
       menu rows that became buttons on 2026-09-19 (Settings, Sign out, Copy, Pin...) grew to the page's 16px
       while the .popover__item rule declares 13 and the Plan row beside them stayed 13. The size comes back. */
    button.popover__item { font-size: var(--lp-text-base); }
    button.popover__item:focus-visible, button.notif-item:focus-visible {
      outline: 2px solid var(--lp-accent-base);
      outline-offset: -2px;
    }

    .popover__item:hover {
      background: var(--lp-wash-hover);
      color: var(--lp-text-primary);
      transition: background var(--lp-motion-instant);
    }
    
    .popover__item--static {
      cursor: default;
      color: var(--lp-text-tertiary);
      font-size: var(--lp-text-sm);
      height: var(--lp-height-sm);
    }
    
    .popover__item--static:hover {
      background: transparent;
      color: var(--lp-text-tertiary);
    }
    
    .popover__divider {
      width: 100%;
      height: 1px;
      background: var(--lp-wash-active);
      margin: var(--lp-space-8) 0;
      border-radius: var(--lp-radius-full);
    }
    
    .popover__item--plan {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
    }
    
    .plan-label {
      color: var(--lp-text-secondary);
      font-size: var(--lp-text-sm);
    }
    
    .plan-tier {
      color: var(--lp-text-tertiary);
      font-size: var(--lp-text-sm);
      display: inline-flex;
      align-items: center;
      gap: 4px;
    }

    /* Crown next to the plan name. Sized in em and inheriting currentColor, so it
       tracks the plan text instead of whatever the OS emoji font decides. */
    .plan-tier__icon {
      flex: none;
      opacity: var(--lp-icon-opacity, 1);
    }
    
    .plan-action {
      margin-left: auto;
      color: var(--lp-text-secondary);
      font-size: var(--lp-text-sm);
      cursor: pointer;
    }
    
    .plan-action:hover {
      color: var(--lp-text-primary);
    }
    
    /* Notifications — unread dot */
    .icon-btn--has-unread::after {
      content: "";
      position: absolute;
      top: var(--lp-space-4);
      right: var(--lp-space-4);
      width: var(--lp-size-2);
      height: var(--lp-size-2);
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
    }
    
    /* Notifications list inside popover */
    .notif-item {
      display: flex;
      align-items: flex-start;
      gap: var(--lp-space-8);
      padding: var(--lp-space-8) var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      cursor: pointer;
      transition: background var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .notif-item:hover {
      background: var(--lp-bg-elevated);
      transition: background var(--lp-motion-instant);
    }
    
    .notif-dot {
      margin-top: var(--lp-space-4);
      width: var(--lp-size-2);
      height: var(--lp-size-2);
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
      flex-shrink: 0;
    }
    
    .notif-content {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      min-width: 0;
    }
    
    .notif-title {
      font-size: var(--lp-text-base);
      font-weight: var(--lp-font-normal);
      color: var(--lp-text-secondary);
      line-height: var(--lp-leading-tight);
    }
    
    .notif-item.notif--unread .notif-title {
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      opacity: 1;
    }
    
    .notif-meta {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
      line-height: var(--lp-leading-tight);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
    /* Notification modal body */
    #notification-modal .modal__body {
      padding: var(--lp-space-20);
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-8);
      overflow-y: auto;
    }

    /* ========================================
       MODAL BASE
       ======================================== */
    
    .modal-backdrop {
      position: fixed;
      inset: 0;
      background: var(--lp-overlay-dark);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: var(--lp-z-modal);
      opacity: 0;
      pointer-events: none;
      /* visibility keeps closed modals out of the accessibility tree and
         search-engine view (opacity alone does not); it transitions as a
         discrete step so the opacity fade is preserved both ways */
      visibility: hidden;
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out),
        visibility var(--lp-motion-mid) var(--lp-ease-out);
    }

    .modal-backdrop--open {
      opacity: 1;
      pointer-events: auto;
      visibility: visible;
    }
    
    /* Stacked dialogs (appear over other modals) */
    .modal-backdrop--stacked {
      z-index: var(--lp-z-popover);
    }
    
    .modal {
      width: 760px;
      max-width: 96vw;
      max-height: 80vh;
      background: var(--lp-bg-surface);
      border-radius: var(--lp-radius-xl);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      box-shadow: var(--lp-shadow-l);
      overflow: hidden;
      display: flex;
      flex-direction: column;
      transform: translateY(20px);
      opacity: 0;
      transition: transform var(--lp-motion-mid) var(--lp-ease-out),
                  opacity var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .modal-backdrop--open .modal {
      transform: translateY(0);
      opacity: 1;
    }
    
    .modal__header,
    .modal__footer {
      padding: var(--lp-space-16) var(--lp-space-20);
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-16);
      flex-shrink: 0;
      /* The Settings footer puts five legal links and the Close button on one row.
         At 390 that row is already wider than the modal, so Close was clipped to
         "Clo" before this pass and would have gone off-screen entirely once the
         links got the tap padding above. Wrapping keeps the exit visible instead of
         trading one fix for a worse defect; on a wide modal there is nothing to wrap
         and the row is unchanged. */
      flex-wrap: wrap;
    }
    
    .modal__body {
      padding: var(--lp-space-20);
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-16);
      overflow-y: auto;
      min-height: var(--lp-modal-min);
    }
    
    .modal__title {
      font-size: var(--lp-text-xl);
      font-weight: var(--lp-font-semibold);
    }
    
    .modal__close {
      width: var(--lp-size-8);
      height: var(--lp-height-sm);
      border-radius: var(--lp-radius-full);
      border: none;
      background: var(--lp-bg-elevated);
      color: var(--lp-text-secondary);
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: var(--lp-text-md);
      transition: background var(--lp-motion-mid) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .modal__close:hover {
      background: var(--lp-bg-surface);
      color: var(--lp-text-primary);
      transition: all var(--lp-motion-instant);
    }
    
    /* Small modal variant */
    .modal--sm {
      width: 400px;
      max-width: 90vw;
    }
    
    .modal--sm .modal__body {
      min-height: 0;
    }
    
    /* Confirm dialog */
    .confirm-dialog {
      z-index: var(--lp-z-popover); /* Above other modals */
    }
    
    .confirm-dialog__content {
      padding: var(--lp-space-24);
      text-align: center;
    }
    
    .confirm-dialog__title {
      font-size: var(--lp-text-lg-plus);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      margin-bottom: var(--lp-space-8);
    }
    
    .confirm-dialog__message {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      margin-bottom: var(--lp-space-20);
    }
    
    .confirm-dialog__actions {
      display: flex;
      justify-content: center;
      gap: var(--lp-space-8);
    }

    /* ========================================
       PROMPT EDITOR MODAL
       ======================================== */
    
    .badge-outline {
      padding: var(--lp-space-4) var(--lp-space-8);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      font-size: var(--lp-text-xs);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-secondary);
    }
    
    /* A label sits 4px above its own field, on every surface (docs/DESIGN-SHARED-VOCABULARY.md, 2026-09-18;
       measured 2026-09-24: the sign-in card and both panels already render 4, with 12-20px to the field
       above, so a label reads as belonging to the field under it). Was 8 here, 4 in the panels. */
    .field-group {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      width: 100%;
    }
    
    .field-group--flex {
      flex: 1;
      min-width: 0;
    }
    
    .field-group--colors {
      flex-shrink: 0;
      width: auto;
    }
    
    .text-label {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
    }
    
    .text-heading {
      font-size: var(--lp-text-lg);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
    }
    
    .text-body {
      font-size: var(--lp-text-base);
      line-height: var(--lp-leading-normal);
      color: var(--lp-text-secondary);
    }
    
    /* Compact metadata row */
    .editor-meta-row {
      display: flex;
      gap: var(--lp-space-16);
      align-items: flex-end;
    }
    
    @media (max-width: 600px) {
      .editor-meta-row {
        flex-direction: column;
        align-items: stretch;
        gap: var(--lp-space-12);
      }
      .field-group--colors {
        width: 100%;
      }
    }
    
    /* Dropdown wrapper */
    .dropdown-wrap {
      position: relative;
    }
    
    .dropdown-list {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      margin-top: var(--lp-space-4);
      max-height: 160px;
      overflow-y: auto;
      background: var(--lp-bg-elevated);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-s);
      box-shadow: var(--lp-shadow-m);
      z-index: var(--lp-z-dropdown);
      opacity: 0;
      pointer-events: none;
      transform: translateY(8px);
      transition: transform var(--lp-motion-fast) var(--lp-ease-out),
                  opacity var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .dropdown-list--open {
      opacity: 1;
      pointer-events: auto;
      transform: translateY(0);
    }
    
    .dropdown-item {
      padding: var(--lp-space-8) var(--lp-space-12);
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      transition: background var(--lp-motion-fast) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .dropdown-item:hover,
    .dropdown-item--active {
      background: var(--lp-bg-surface);
      color: var(--lp-text-primary);
    }
    
    .dropdown-item--create {
      border-top: 1px solid var(--lp-stroke-default);
      color: var(--lp-text-secondary);
    }
    
    .editor-tags {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--lp-space-16);
    }
    
    .tag-colors {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      flex-wrap: wrap;
      height: var(--lp-height-lg);
    }
    
    .tag-dot {
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thick) solid transparent;
      cursor: pointer;
      transition: transform var(--lp-motion-mid) var(--lp-ease-out),
                  border-color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .tag-dot:hover {
      transform: scale(1.15);
      transition: transform var(--lp-motion-instant), border-color var(--lp-motion-instant);
    }
    
    .tag-dot.active {
      border-color: var(--lp-text-primary);
    }
    
    .textarea-shell {
      position: relative;
    }
    
    .textarea-copy {
      position: absolute;
      right: var(--lp-space-12);
      top: var(--lp-space-12);
      /* v2.7 (T6): floating chip needs its own surface — long prompt lines used
         to run straight under the bare text and both became unreadable. */
      border: 1px solid var(--lp-stroke-default);
      background: var(--lp-bg-elevated);
      border-radius: var(--lp-radius-s);
      padding: var(--lp-space-4);
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
      cursor: pointer;
      position: absolute;
    }

    .textarea-copy::before {
      content: "";
      position: absolute;
      inset: -10px;
    }

    .textarea-copy:hover {
      color: var(--lp-text-primary);
    }

    /* v2.7 (T6): reserve space so prompt text never starts under the Copy chip */
    .textarea-shell .textarea { padding-right: 64px; }

    /* ========================================
       SPOTLIGHT MODAL — Master v1.4 §6.3
       ======================================== */
    
    /* Empty states */

    /* ========================================
       MANAGE COLLECTIONS MODAL
       ======================================== */
    
    .collections-modal .modal {
      width: 560px;
      max-height: 70vh;
    }
    
    .collections-modal .modal__body {
      min-height: 0;
    }
    
    .collections-list {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      max-height: 50vh;
      overflow-y: auto;
    }
    
    .collections-row {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      padding: var(--lp-space-8) var(--lp-space-16);
      min-height: var(--lp-height-lg);
      cursor: pointer;
      background: transparent;
      border-radius: var(--lp-radius-m);
      transition: background var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .collections-row:hover {
      background: var(--lp-wash-hover);
      transition: background var(--lp-motion-instant);
    }
    
    .collections-row--active::before {
      content: "";
      position: absolute;
      left: 0;
      top: var(--lp-space-4);
      bottom: var(--lp-space-4);
      width: 2px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
    }
    
    .collections-row-main {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      min-width: 0;
    }
    
    .collections-row-name {
      font-size: var(--lp-text-base);
      font-weight: var(--lp-font-medium);
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
    
    .collections-row-meta {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
    }
    
    .collections-row-actions {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      flex-shrink: 0;
    }
    
    /* Collections row drag handle */
    .collections-row-handle {
      width: var(--lp-size-6);
      height: var(--lp-size-6);
      border: none;
      padding: 0;
      border-radius: var(--lp-radius-full);
      background: transparent;
      color: var(--lp-text-tertiary);
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: grab;
      opacity: 0;
      transition: opacity var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .collections-row:hover .collections-row-handle,
    .collections-row--reorder-mode .collections-row-handle {
      opacity: 1;
    }
    
    .collections-row-handle:active {
      cursor: grabbing;
    }
    
    .collections-row--dragging {
      opacity: var(--lp-opacity-subtle);
    }
    
    .collections-row--drop-target {
      background: var(--lp-wash-active);
    }
    
    /* Kebab menu */
    .kebab-menu {
      position: absolute;
      right: 0;
      top: calc(100% + var(--lp-space-4));
      width: 160px;
      padding: var(--lp-space-4);
      background: var(--lp-bg-elevated);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-m);
      box-shadow: var(--lp-shadow-m);
      z-index: var(--lp-z-dropdown);
    }
    
    .kebab-menu--fixed {
      position: fixed;
      z-index: var(--lp-z-top); /* Above modals */
    }
    
    .kebab-menu--up {
      top: auto;
      bottom: calc(100% + var(--lp-space-4));
    }
    
    .kebab-menu__item {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      padding: var(--lp-space-8) var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      transition: background var(--lp-motion-fast) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .kebab-menu__item:hover {
      background: var(--lp-wash-hover);
      color: var(--lp-text-primary);
      transition: background var(--lp-motion-instant), color var(--lp-motion-instant);
    }
    
    .kebab-menu__item--danger:hover {
      background: var(--lp-overlay-error);
      color: var(--lp-error-text);
    }
    
    /* Inline rename input */
    .collections-rename-input {
      height: var(--lp-height-sm);
      padding: 0 var(--lp-space-8);
      font-size: var(--lp-text-base);
    }

    /* ========================================
       LOADING STATES
       ======================================== */
    
    /* Spinner */
    .spinner {
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      border: var(--lp-border-thick) solid var(--lp-stroke-default);
      border-top-color: var(--lp-accent-base);
      border-radius: var(--lp-radius-full);
      animation: spin var(--lp-anim-spin) linear infinite;
    }
    
    .spinner--sm { width: 12px; height: 12px; border-width: 1.5px; }
    .spinner--lg { width: var(--lp-size-6); height: var(--lp-size-6); border-width: 2.5px; }
    
    @keyframes spin {
      to { transform: rotate(360deg); }
    }
    
    /* Button loading state */
    .btn--loading {
      position: relative;
      color: transparent !important;
      pointer-events: none;
    }
    
    .btn--loading::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      width: var(--lp-icon-sm);
      height: var(--lp-icon-sm);
      margin: -8px 0 0 -8px;
      border: var(--lp-border-thick) solid currentColor;
      border-top-color: transparent;
      border-radius: var(--lp-radius-full);
      animation: spin var(--lp-anim-spin) linear infinite;
    }
    
    .btn--primary.btn--loading::after {
      border-color: var(--lp-overlay-light-border);
      border-top-color: var(--lp-text-on-accent);
    }
    
    /* Skeleton placeholder */
    /* A CALM SKELETON (2026-09-04). The old one slid a light band across every placeholder every
       2.2s: motion travelling sideways draws the eye to the loading state, which is the one thing
       on screen with nothing to read. This breathes instead: the surface fades gently between two
       adjacent greys, no movement, no direction, nothing to track. Kept: the exact same box model,
       so it still reserves the same space and causes no layout shift, and the reduced-motion block
       further down still flattens it to a static fill. */
    .skeleton {
      background: var(--lp-bg-surface);
      animation: skeleton-breathe var(--lp-anim-skeleton) ease-in-out infinite;
      border-radius: var(--lp-radius-s);
    }
    
    @keyframes skeleton-breathe {
      0%, 100% { background-color: var(--lp-bg-surface); }
      50%      { background-color: var(--lp-bg-elevated); }
    }
    
    .skeleton--text {
      height: var(--lp-icon-sm);
      width: 100%;
      margin-bottom: var(--lp-space-8);
    }
    
    .skeleton--text:last-child {
      width: 60%;
      margin-bottom: 0;
    }
    
    .skeleton--card {
      height: 180px;
    }
    
    /* v2.6: skeleton container layouts */
    .skeleton-row {
      padding: var(--lp-space-12) var(--lp-space-16);
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-8);
    }
    .skeleton-row .skeleton--text {
      height: 12px;
      margin: 0;
    }
    .collections-skeleton {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
      gap: var(--lp-space-16);
    }
    
    /* Loading overlay for sections */
    .loading-overlay {
      position: absolute;
      inset: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      background: var(--lp-overlay-glass);
      border-radius: inherit;
      z-index: var(--lp-z-dropdown);
    }

    /* ========================================
       TOAST
       ======================================== */
    
    .toast {
      position: fixed;
      bottom: 24px;
      left: 50%;
      transform: translateX(-50%) translateY(8px);
      padding: var(--lp-space-12) var(--lp-space-16);
      background: var(--lp-bg-elevated);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-m);
      font-size: var(--lp-text-base);
      color: var(--lp-text-primary);
      box-shadow: var(--lp-shadow-m);
      opacity: 0;
      pointer-events: none;
      transition: opacity var(--lp-motion-fast) var(--lp-ease-out),
                  transform var(--lp-motion-fast) var(--lp-ease-out);
      z-index: var(--lp-z-top);
    }
    
    .toast--visible {
      opacity: 1;
      pointer-events: auto;
      transform: translateX(-50%) translateY(0);
    }

    /* Undo-delete toast variant — inline Undo button with accent color */
    .toast--undo {
      display: inline-flex;
      align-items: center;
      gap: var(--lp-space-12);
    }
    .toast__undo-btn {
      padding: var(--lp-space-4) var(--lp-space-12);
      background: transparent;
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-xs);
      color: var(--lp-accent-text);
      font-size: var(--lp-text-xs);
      font-weight: var(--lp-font-medium);
      font-family: inherit;
      cursor: pointer;
      transition: background var(--lp-motion-fast), border-color var(--lp-motion-fast);
    }
    .toast__undo-btn:hover {
      background: var(--lp-wash-hover);
      border-color: var(--lp-accent-base);
    }
    .toast__undo-btn:focus-visible {
      outline: 2px solid var(--lp-accent-base);
      outline-offset: 2px;
    }

    /* ========================================
       OFFLINE BANNER
       ======================================== */
    
    .offline-banner {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      padding: var(--lp-space-8) var(--lp-space-16);
      background: var(--lp-warning);
      color: #1A1A1A;
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-medium);
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--lp-space-8);
      z-index: var(--lp-z-top);
      transform: translateY(-100%);
      transition: transform var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .offline-banner--visible {
      transform: translateY(0);
    }
    
    .offline-banner__icon {
      font-size: var(--lp-text-md);
    }
    
    /* Adjust topbar when offline banner is visible */
    .is-offline .topbar {
      margin-top: 36px;
    }
    
    .is-offline .sidebar {
      padding-top: calc(var(--lp-space-20) + 36px);
    }

    /* ========================================
       ONE SCROLLBAR (approved 2026-09-23, design system 10.x)
       The same bar on the web app, both panels and the extension: 6px, a transparent track,
       the thumb in the default stroke, lighter under the pointer; Firefox thin with the same
       colours. Measured 23/09 before this rule: three variants in this file (8px on a grey track,
       the filter strip, the Spotlight) and the panels on the OS default. Nothing below may
       restyle a scrollbar; a surface that needs one hidden hides overflow instead.
       ======================================== */
    * { scrollbar-width: thin; scrollbar-color: var(--lp-stroke-default) transparent; }
    *::-webkit-scrollbar { width: 6px; height: 6px; }
    *::-webkit-scrollbar-track { background: transparent; }
    *::-webkit-scrollbar-thumb { background: var(--lp-stroke-default); border-radius: 3px; }
    *::-webkit-scrollbar-thumb:hover { background: var(--lp-stroke-light); }
    *::-webkit-scrollbar-corner { background: transparent; }
    /* Flash, then rest (Kenz, 2026-09-23, design system 10.x "Scrollbars flash, then rest"). On a pointer device
       the thumb is clear at rest. It shows for about a second when a region opens and while it scrolls
       (public/lp-scrollbars.js marks both with data-lp-scroll, then fades it), and while the pointer is over
       the area or the region has keyboard focus. Lighter while it is actively scrolling. Touch screens keep
       their own overlay bars. Hovering a child counts, because :hover holds for every ancestor. */
    @media (hover: hover) and (pointer: fine) {
      * { scrollbar-color: transparent transparent; }
      *:hover, *:focus-visible, [data-lp-scroll] { scrollbar-color: var(--lp-stroke-default) transparent; }
      [data-lp-scroll="active"] { scrollbar-color: var(--lp-stroke-light) transparent; }
      *::-webkit-scrollbar-thumb { background: transparent; }
      *:hover::-webkit-scrollbar-thumb, *:focus-visible::-webkit-scrollbar-thumb, [data-lp-scroll]::-webkit-scrollbar-thumb { background: var(--lp-stroke-default); }
      [data-lp-scroll="active"]::-webkit-scrollbar-thumb, *:hover::-webkit-scrollbar-thumb:hover { background: var(--lp-stroke-light); }
    }

    /* ========================================
       RESPONSIVE
       ======================================== */
    
    @media (max-width: 1200px) {
      .collections-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    }
    
    @media (max-width: 992px) {
      .search-trigger { width: 36px; padding: 0; justify-content: center; }
      .search-trigger__text, .search-trigger__kbd { display: none; }
      .topbar { padding-inline: var(--lp-space-16); }
      .page-inner { padding-inline: var(--lp-space-16); }
      .collections-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    }
    
    @media (max-width: 768px) {
      .sidebar {
        position: fixed;
        left: 0;
        top: 0;
        bottom: 0;
        width: 220px;
        transform: translateX(-100%);
        transition: transform var(--lp-motion-mid) var(--lp-ease-out);
        z-index: var(--lp-z-modal);
        /* No shadow while closed: translated off-screen, its 40px blur still reached ~12px into the
           left edge of every phone screen as a grey band (27/09). The shadow belongs to the open drawer. */
        box-shadow: none;
      }
      .sidebar--open-mobile { transform: translateX(0); box-shadow: var(--lp-shadow-l); }
      .sidebar__toggle { display: none; }
      .topbar__left { display: flex; }
      .topbar__toggle-mobile { display: flex; }
      .page-inner { padding-top: var(--lp-space-24); padding-bottom: var(--lp-space-24); }
      .topbar__right { gap: var(--lp-space-8); }
      .spotlight { max-width: 100%; margin: var(--lp-space-16); }
      .spotlight-backdrop { padding-top: 80px; }
    }
    
    @media (max-width: 520px) {
      .collections-grid { grid-template-columns: minmax(0, 1fr); }
    }

    /* ========================================
       NEW SESSION / SESSION INPUT BAR
       ======================================== */
    
    .ns-hero {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      min-height: 50vh;
      gap: var(--lp-space-24);
      text-align: center;
    }
    
    .ns-hero__title {
      font-size: var(--lp-text-3xl);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
    }
    
    .ns-hero__sub {
      font-size: var(--lp-text-md);
      color: var(--lp-text-secondary);
      max-width: 400px;
    }

    /* Session content wrapper - scrolls, input bar stays fixed */
    .session-content {
      flex: 1;
      display: flex;
      flex-direction: column;
      min-height: 0;
      overflow-y: auto;    }
        
    /* Right padding so bubbles don't touch scrollbar */
    
    .ns-landing {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      text-align: center;
      padding: var(--lp-space-24) 0;
    }
    
    .session-content--active .ns-landing {
      display: none;
    }
    
    .session-stream {
      display: none;
      flex-direction: column;
      gap: var(--lp-space-20);
      padding-top: var(--lp-space-24);
      padding-right: var(--lp-space-8);
      padding-bottom: var(--lp-space-24);
    }
    
    .session-content--active .session-stream {
      display: flex;
    }

    .ns-landing-eyebrow {
      font-size: var(--lp-text-xs);
      font-weight: var(--lp-font-semibold);
      text-transform: uppercase;
      letter-spacing: var(--lp-tracking-wide);
      color: var(--lp-text-tertiary);
      margin-bottom: var(--lp-space-12);
    }

    .ns-hints-row {
      display: flex;
      flex-wrap: wrap;
      gap: var(--lp-space-8);
      justify-content: center;
    }

    .ns-hint {
      height: var(--lp-height-sm);
      padding: 0 var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
      display: inline-flex;
      align-items: center;
      white-space: nowrap;
      cursor: pointer;
      transition: background var(--lp-motion-fast) var(--lp-ease-out),
                  border-color var(--lp-motion-fast) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out),
                  transform var(--lp-motion-fast) var(--lp-ease-out);
    }

    .ns-hint:hover {
      background: var(--lp-bg-elevated);
      border-color: var(--lp-stroke-light);
      color: var(--lp-text-primary);
      transform: translateY(-0.5px);
    }
    
    .ns-hint:focus-visible {
      outline: none;
      box-shadow: var(--lp-focus-ring);
    }
    
    .ns-input-bar-shell {
      flex-shrink: 0;
      padding-top: var(--lp-space-24);
      /* Fallback for browsers that don't support env() */
      padding-bottom: var(--lp-space-24);
      padding-bottom: calc(var(--lp-space-24) + env(safe-area-inset-bottom, 0px));
      background: var(--lp-bg-base);
    }
    
    .ns-input-bar {
      min-height: var(--lp-sidebar-collapsed);
      border-radius: var(--lp-radius-l);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      box-shadow: var(--lp-shadow-m);
      padding: var(--lp-space-12) var(--lp-space-16);
      display: flex;
      align-items: center;
      gap: var(--lp-space-12);
      max-width: var(--lp-input-bar-max);
      margin-inline: auto;
      transition: border-color var(--lp-motion-fast) var(--lp-ease-out),
                  box-shadow var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .ns-input-bar:focus-within {
      border-color: var(--lp-accent-base);
      box-shadow: var(--lp-shadow-l);
      /* No transform - matte, no bounce */
    }
    
    .ns-input-wrap {
      flex: 1;
      position: relative;
    }
    
    .ns-input-field {
      width: 100%;
      min-height: var(--lp-height-md);
      max-height: 5.25rem; /* ~3 lines */
      border-radius: var(--lp-radius-m);
      border: none;
      background: var(--lp-bg-surface);
      padding: calc((var(--lp-height-md) - var(--lp-text-base) * 1.5) / 2) var(--lp-space-12);
      padding-right: 96px;
      font-size: var(--lp-text-base);
      font-size: max(16px, var(--lp-text-base)); /* Prevent iOS zoom */
      color: var(--lp-text-primary);
      font-family: inherit;
      outline: none;
      resize: none;
      line-height: 1.5;
      overflow-y: auto;
    }
    
    .ns-input-field::placeholder {
      color: var(--lp-text-secondary);
    }
    
    .ns-input-field--pulse {
      animation: inputPulse var(--lp-anim-pulse) ease-in-out 3;
    }
    
    @keyframes inputPulse {
      0%, 100% { box-shadow: 0 0 0 0 transparent; }
      50% { box-shadow: 0 0 0 4px var(--lp-overlay-accent); }
    }
    
    .ns-input-field:disabled {
      opacity: var(--lp-opacity-muted);
      cursor: not-allowed;
    }
    
    .ns-mode-addon {
      position: absolute;
      right: var(--lp-space-4);
      top: 50%;
      transform: translateY(-50%);
      height: var(--lp-height-sm);
      padding: 0 var(--lp-space-12);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid transparent;
      background: transparent;
      display: inline-flex;
      align-items: center;
      gap: var(--lp-space-8);
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
      cursor: pointer;
    }
    
    .ns-mode-addon::after {
      content: "▾";
      font-size: var(--lp-text-2xs);
      margin-left: 0;
      color: var(--lp-text-tertiary);
    }
    
    .ns-mode-addon:hover {
      color: var(--lp-text-primary);
      border-color: var(--lp-stroke-light);
      background: var(--lp-wash-subtle);
    }
    
    .ns-mode-addon:hover::after {
      color: var(--lp-text-secondary);
    }
    
    .ns-mode-pill {
      width: var(--lp-size-2);
      height: var(--lp-size-2);
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
    }
    
    .ns-mode-pill[data-pill="Prompt"] { background: var(--lp-mode-prompt); }
    .ns-mode-pill[data-pill="Custom AI"] { background: var(--lp-mode-custom-ai); }
    
    .ns-mode-popover {
      position: absolute;
      bottom: calc(100% + 8px);
      right: 0;
      min-width: 220px;
      padding: var(--lp-space-8);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      box-shadow: var(--lp-shadow-m);
      opacity: 0;
      pointer-events: none;
      transform: translateY(4px);
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out),
                  transform var(--lp-motion-mid) var(--lp-ease-out);
      z-index: var(--lp-z-dropdown);
    }
    
    .ns-mode-popover--open {
      opacity: 1;
      pointer-events: auto;
      transform: translateY(0);
    }
    
    .ns-mode-option {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      padding: var(--lp-space-8) var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      cursor: pointer;
      transition: background var(--lp-motion-mid) var(--lp-ease-out);
    }
    .ns-mode-option + .ns-mode-option {
      margin-top: 2px;
    }
    
    .ns-mode-option:hover {
      background: var(--lp-bg-elevated);
      transition: background var(--lp-motion-instant);
    }
    
    .ns-mode-option--active {
      color: var(--lp-text-primary);
      background: var(--lp-wash-hover);
    }
    .ns-mode-option--active:hover {
      background: var(--lp-wash-hover);
    }
    
    .ns-mode-pro-tag {
      font-size: var(--lp-text-2xs);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-tertiary);
      margin-left: var(--lp-space-4);
    }
    
    .ns-send-circle {
      width: var(--lp-size-10);
      height: var(--lp-height-md);
      border-radius: var(--lp-radius-full);
      border: none;
      background: var(--lp-accent-base);
      cursor: pointer;
      position: relative;
      transition: background var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .ns-send-circle::after {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-40%, -50%);
      border: 5px solid transparent;
      border-left: 8px solid var(--lp-text-on-accent);
    }
    
    .ns-send-circle:hover {
      background: var(--lp-accent-hover);
      transition: background var(--lp-motion-instant);
    }
    
    .ns-send-circle--loading {
      pointer-events: none;
      opacity: var(--lp-opacity-loading);
    }
    
    .ns-send-circle--loading::after {
      border: none;
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      border-radius: var(--lp-radius-full);
      border-top: var(--lp-border-thick) solid var(--lp-text-on-accent);
      border-right: 2px solid transparent;
      transform: translate(-50%, -50%);
      animation: sendSpin var(--lp-anim-spin-fast) linear infinite;
    }
    
    @keyframes sendSpin {
      to { transform: translate(-50%, -50%) rotate(360deg); }
    }
    
    /* The footer is a two-item row (credits on the left, disclaimer on the right) laid out with
       space-between. When the credit counter is absent, and it is absent for a signed-out visitor
       and for team members, space-between leaves the single remaining child on the LEFT, so the
       disclaimer jumps sides depending on who is looking. Measured on staging at 390px: one child,
       x=32, i.e. hard left. margin-left:auto pins it right whether or not it has a sibling. */
    .ns-input-footer > .ns-disclaimer:only-child,
    .ns-input-footer > .ns-disclaimer { margin-left: auto; }

    .ns-input-footer {
      max-width: var(--lp-input-bar-max);
      margin: var(--lp-space-4) auto 0 auto;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
    }

    /* ========================================
       SESSION STREAM (CHAT BUBBLES)
       ======================================== */
    
    .bubble {
      padding: var(--lp-space-16) var(--lp-space-20);
      border-radius: var(--lp-radius-l);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      max-width: var(--lp-bubble-max);
      animation: bubble-enter var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    @keyframes bubble-enter {
      from { opacity: 0; transform: translateY(8px); }
      to { opacity: 1; transform: translateY(0); }
    }
    
    .bubble--user {
      align-self: flex-end;
      background: var(--lp-bg-elevated);
      border-color: var(--lp-stroke-light);
      max-width: var(--lp-bubble-user-max);
    }
    
    .bubble--user .bubble__meta {
      justify-content: flex-end;
    }
    
    .bubble--lp {
      align-self: flex-start;
      background: var(--lp-bg-surface);
    }
    
    /* The engine's label line, e.g. "[create] Email [English]". It sits above the prompt and is
       never part of what the person copies; promptText.js owns that split. */
    .bubble__label {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
      margin-bottom: var(--lp-space-4);
    }

    .bubble__meta {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      margin-bottom: var(--lp-space-8);
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
    }
    
    .bubble__meta-sep {
      width: 3px;
      height: 3px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-text-tertiary);
      opacity: var(--lp-opacity-muted);
    }
    
    .bubble__title {
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-secondary);
    }
    
    .bubble__body {
      font-size: var(--lp-text-base);
      line-height: var(--lp-leading-normal);
      color: var(--lp-text-primary);
      white-space: pre-wrap;
      overflow-wrap: anywhere;
      word-break: break-word;
    }
    
    .bubble__footer {
      display: flex;
      justify-content: flex-end;
      gap: var(--lp-space-12);
      margin-top: var(--lp-space-12);
      padding-top: var(--lp-space-12);
      border-top: 1px solid var(--lp-stroke-default);
    }
    
    .lp-icon-mark {
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      border-radius: var(--lp-radius-full);
      border: var(--lp-border-thick) solid var(--lp-accent-base);
      flex-shrink: 0;
    }

    /* ========================================
       APPS PAGE
       ======================================== */
    
    .apps-list {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-12);
    }
    
    .app-card {
      display: flex;
      align-items: center;
      gap: var(--lp-space-12);
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      transition: border-color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .app-card:hover {
      border-color: var(--lp-stroke-light);
      transition: border-color var(--lp-motion-instant);
    }
    
    .app-card__icon {
      width: var(--lp-size-10);
      height: var(--lp-height-md);
      border-radius: var(--lp-radius-s);
      background: var(--lp-bg-elevated);
      flex-shrink: 0;
    }
    
    .app-card__main {
      flex: 1;
      min-width: 0;
    }
    
    .app-card__name {
      font-size: var(--lp-text-md);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-primary);
      margin-bottom: var(--lp-space-8);
    }
    
    .app-card__desc {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      margin-bottom: var(--lp-space-8);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    
    .app-card__meta {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
    }
    
    .app-card__meta-dot {
      width: 3px;
      height: 3px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-text-tertiary);
    }
    
    .app-card__right {
      flex-shrink: 0;
    }
    
    .btn--micro {
      height: 28px;
      min-width: 60px;
      padding: 0 var(--lp-space-12);
      font-size: var(--lp-text-sm);
    }

    /* ========================================
       HISTORY PAGE
       ======================================== */
    
    .history-sections {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-24);
    }
    
    .history-section__title {
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-tertiary);
      text-transform: uppercase;
      letter-spacing: var(--lp-tracking-wide);
      margin-bottom: var(--lp-space-12);
    }
    
    .history-list {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-12);
    }
    
    .history-item {
      display: flex;
      align-items: center;
      gap: var(--lp-space-16);
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      transition: border-color var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .history-item:hover {
      border-color: var(--lp-stroke-light);
      transition: border-color var(--lp-motion-instant);
    }
    
    .history-item__main {
      flex: 1;
      min-width: 0;
    }
    
    .history-item__title-row {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      margin-bottom: var(--lp-space-8);
    }
    
    .history-item__title {
      font-size: var(--lp-text-md);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-primary);
    }
    
    .history-item__pin-dot {
      width: 6px;
      height: 6px;
      border-radius: var(--lp-radius-full);
      background: var(--lp-accent-base);
    }
    
    .history-item__preview {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      margin-bottom: var(--lp-space-8);
    }
    
    .history-item__meta {
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
    }
    
    .history-item__actions {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      flex-shrink: 0;
    }
    
    .history-item .kebab-btn {
      width: var(--lp-size-6);
      height: var(--lp-size-6);
      position: relative;
    }

    /* The glyph stays 24px; the TAP is 44px. Same trick as the collection chips: an invisible
       pseudo-element widens the hit area without changing the row's spacing. */
    .history-item .kebab-btn::before {
      content: "";
      position: absolute;
      inset: -10px;
    }

    /* ========================================
       EMPTY STATE
       ======================================== */
    

    /* ========================================
       AFFILIATE PAGE
       ======================================== */

    /* v2.7 (T8): quick status strip — 4 tappable tiles above the panels */
    .affiliate-status-strip {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 12px;
      margin-bottom: 20px;
    }
    .affiliate-status-strip.is-empty {
      display: block;
      padding: 14px 16px;
      border: 1px solid var(--lp-stroke-default);
      border-radius: 12px;
      color: var(--lp-text-tertiary);
    }
    .status-stat {
      text-align: left;
      background: var(--lp-bg-surface);
      border: 1px solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-m);
      padding: var(--lp-space-12) var(--lp-space-16);
      cursor: pointer;
      font: inherit;
      color: inherit;
      transition: background .15s ease, border-color .15s ease;
    }
    .status-stat:hover { background: var(--lp-bg-elevated); border-color: var(--lp-stroke-light); }
    .status-stat:focus-visible { outline: 2px solid var(--lp-accent-base); outline-offset: 2px; }
    .status-stat__value { font-size: var(--lp-text-2xl); font-weight: 600; color: var(--lp-text-primary); margin-top: 2px; }
    .status-stat__sub { font-size: 12px; color: var(--lp-text-tertiary); margin-top: 4px; }
    .status-progress { height: 4px; border-radius: 2px; background: var(--lp-bg-input); margin-top: 8px; overflow: hidden; }
    .status-progress__bar { height: 100%; background: var(--lp-accent-base); border-radius: 2px; }
    @media (max-width: 640px) { .affiliate-status-strip { grid-template-columns: repeat(2, 1fr); } }

    .affiliate-panels {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-16);
    }
    
    .affiliate-panel {
      border-radius: var(--lp-radius-l);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-surface);
      overflow: hidden;
    }
    
    .affiliate-panel__header {
      padding: var(--lp-space-16) var(--lp-space-20);
      border-bottom: 1px solid var(--lp-stroke-default);
    }
    
    .affiliate-panel__title {
      font-size: var(--lp-text-lg);
      font-weight: var(--lp-font-medium);
    }
    
    .affiliate-panel__body {
      padding: var(--lp-space-20);
    }
    
    .affiliate-product-layout {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: var(--lp-space-24);
    }
    
    .affiliate-referral-inline {
      display: flex;
      gap: var(--lp-space-8);
    }
    
    .affiliate-referral-inline .input {
      flex: 1;
    }
    /* A locked link is a sentence with its button under it (27/09). */
    .affiliate-referral-inline:has(.affiliate-referral-locked),
    .affiliate-referral-inline:has(.affiliate-referral-link) { flex-direction: column; align-items: flex-start; }
    /* The referral link reads whole: it wraps inside a field-shaped box instead of scrolling out of one (27/09). */
    .affiliate-referral-link {
      align-self: stretch;
      margin: 0;
      padding: var(--lp-space-8) var(--lp-space-12);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-base);
      font-size: var(--lp-text-base);
      line-height: var(--lp-leading-normal);
      color: var(--lp-text-primary);
      overflow-wrap: anywhere;
      user-select: all;
    }
    .affiliate-referral-locked {
      margin: 0;
      font-size: var(--lp-text-base);
      line-height: var(--lp-leading-normal);
      color: var(--lp-text-secondary);
    }
    
    .affiliate-preview-layout {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: var(--lp-space-24);
    }
    
    .affiliate-preview-box {
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-base);
    }
    
    .affiliate-preview-box__value-main {
      font-size: var(--lp-text-2xl);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      margin: var(--lp-space-8) 0 var(--lp-space-4);
    }
    
    .affiliate-preview-box__value-secondary {
      font-size: var(--lp-text-md);
      color: var(--lp-text-secondary);
      margin-bottom: var(--lp-space-8);
    }
    
    .affiliate-steps {
      display: flex;
      gap: var(--lp-space-16);
      list-style: none;
      margin-bottom: var(--lp-space-16);
    }
    
    .affiliate-step {
      flex: 1;
      padding: var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      background: var(--lp-bg-base);
    }
    
    .affiliate-path-actions {
      display: flex;
      gap: var(--lp-space-8);
      margin-top: var(--lp-space-16);
    }
    
    .affiliate-table {
      width: 100%;
      border-collapse: collapse;
      font-size: var(--lp-text-base);
    }
    
    .affiliate-table th,
    .affiliate-table td {
      padding: var(--lp-space-8) var(--lp-space-12);
      text-align: left;
      color: var(--lp-text-secondary);
      border-bottom: 1px solid var(--lp-stroke-default);
    }
    
    .affiliate-table th {
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-tertiary);
      font-size: var(--lp-text-xs);
      text-transform: uppercase;
    }
    
    .metric-tile {
      padding: var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      background: var(--lp-bg-base);
    }
    
    .metric-tile__value {
      font-size: var(--lp-text-xl-plus);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      margin-top: var(--lp-space-4);
    }
    
    /* Hint icons and text */
    /* Zeroed status strip: same layout, quieter, nothing clickable because there is nothing to
       open yet. */
    /* Zero is shown by the numbers in the secondary colour, not by fading the tile: opacity 0.72 put every label
       and sub-line under AA in both themes (axe, 27/09, the first time the demo showed a Free account at zero). */
    .affiliate-status-strip--zero .status-stat { cursor: default; }
    .affiliate-status-strip--zero .status-stat__value { color: var(--lp-text-secondary); }

    /* Legal and exit links inside the auth card render 14px tall as text; the tap target should
       not be. Measured at 390px: "Not now, take me back…", "Terms of Service" and "Privacy Policy"
       all came back under the 44px floor. Vertical padding buys the height without moving the
       layout, since that card is a single column. */
    .auth-exit a,
    .auth-legal a { display: inline-block; padding: 8px 2px; }

    /* The Settings footer carries the same three legal links as the auth card, in a
       div of its own rather than .auth-legal, so the fix shipped for that card never
       reached here: measured 32x13, 40x13 and 39x13 at 390x844, signed in. Same
       treatment as the line above rather than a second pattern: padding keeps them
       reading as inline legal text while giving the finger something to land on. */
    .seft-fix-size a { display: inline-block; padding: 8px 2px; }

    .hint-icon {
      position: relative;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: var(--lp-icon-sm);
      height: var(--lp-icon-sm);
      border-radius: var(--lp-radius-full);
      background: var(--lp-wash-strong);
      color: var(--lp-text-tertiary);
      font-size: var(--lp-text-2xs);
      font-weight: var(--lp-font-semibold);
      cursor: pointer;
      margin-left: var(--lp-space-4);
      vertical-align: middle;
      transition: background var(--lp-motion-fast) var(--lp-ease-out),
                  color var(--lp-motion-fast) var(--lp-ease-out);
      -webkit-tap-highlight-color: transparent;
    }
    
    /* Larger touch target */
    .hint-icon::before {
      content: '';
      position: absolute;
      inset: -8px;
    }
    
    .hint-icon:hover,
    .hint-icon:focus,
    .hint-icon.hint-icon--active {
      background: var(--lp-wash-strong);
      color: var(--lp-text-primary);
    }
    
    /* Custom tooltip - rendered via JS to avoid overflow issues */
    .hint-tooltip {
      position: fixed;
      width: max-content;
      max-width: 280px;
      padding: var(--lp-space-8) var(--lp-space-12);
      background: var(--lp-bg-elevated);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      border-radius: var(--lp-radius-s);
      box-shadow: var(--lp-shadow-m);
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-normal);
      line-height: var(--lp-leading-snug);
      color: var(--lp-text-secondary);
      white-space: normal;
      text-align: left;
      z-index: var(--lp-z-top);
      opacity: 0;
      pointer-events: none;
      transform: translateY(4px);
      transition: transform var(--lp-motion-fast) var(--lp-ease-out),
                  opacity var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .hint-tooltip--visible {
      opacity: 1;
      visibility: visible;
      transform: translateY(0);
    }
    
    .modal__title .hint-icon,
    .content-title .hint-icon {
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      font-size: var(--lp-text-xs);
    }
    
    .affiliate-earnings-overview {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: var(--lp-space-12);
      margin-bottom: var(--lp-space-16);
    }

    .affiliate-vouchers-list {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-8);
    }

    .affiliate-voucher-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      padding: var(--lp-space-12);
      border-radius: var(--lp-radius-s);
      background: var(--lp-bg-base);
    }

    .affiliate-voucher-row__actions {
      display: flex;
      gap: var(--lp-space-8);
      flex-shrink: 0;
    }

    .affiliate-guide-toggle {
      margin-top: var(--lp-space-8);
    }

    .affiliate-guide-content {
      margin-top: var(--lp-space-12);
      padding: var(--lp-space-20);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-base);
    }
    
    .affiliate-guide-content a {
      color: var(--lp-text-primary);
      text-decoration: underline;
      text-underline-offset: 2px;
      transition: opacity var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .affiliate-guide-content a:hover {
      opacity: 0.7;
    }
    
    .guide-section {
      margin-bottom: var(--lp-space-20);
    }
    
    .guide-section:last-child {
      margin-bottom: 0;
    }
    
    .guide-section__title {
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-tertiary);
      text-transform: uppercase;
      letter-spacing: 0.05em;
      margin-bottom: var(--lp-space-8);
    }
    
    .guide-section__body {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
      line-height: var(--lp-leading-relaxed);
    }
    
    .guide-templates {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-8);
    }
    
    .guide-template {
      padding: var(--lp-space-12);
      background: var(--lp-bg-elevated);
      border-radius: var(--lp-radius-s);
      font-size: var(--lp-text-sm);
      line-height: var(--lp-leading-normal);
    }
    
    .guide-template__label {
      display: inline-block;
      color: var(--lp-text-tertiary);
      min-width: 70px;
      padding-right: var(--lp-space-8);
    }
    
    .guide-template__text {
      color: var(--lp-text-secondary);
    }
    
    .guide-platforms {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-12);
    }
    
    .guide-platform {
      padding: var(--lp-space-12);
      background: var(--lp-wash-subtle);
      border-radius: var(--lp-radius-s);
    }
    
    .guide-platform__name {
      font-weight: var(--lp-font-semibold);
      font-size: var(--lp-text-base);
      color: var(--lp-text-primary);
      margin-bottom: var(--lp-space-4);
    }
    
    .guide-platform__format {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
      margin-bottom: var(--lp-space-8);
    }
    
    .guide-platform__do {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
      margin-bottom: var(--lp-space-4);
    }
    
    .guide-platform__do::before {
      content: "✓ ";
      color: var(--lp-success-text);
    }
    
    .guide-platform__dont {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
    }
    
    .guide-platform__dont::before {
      content: "✗ ";
      color: var(--lp-error-text);
    }

    .affiliate-payouts-summary {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: var(--lp-space-12);
      margin-bottom: var(--lp-space-16);
    }

    /* The payout method is an L1 group (2026-09-25); the sheet's summary tiles and history table sit around it. */
    .payout-method {
      margin-bottom: var(--lp-space-32);
    }

    .affiliate-table--wrap td {
      word-break: break-all;
      max-width: 200px;
    }


    .payment-plan-summary {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-base);
      margin-bottom: var(--lp-space-16);
    }

    .payment-form {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-12);
    }

    .payment-footer-row {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--lp-space-12);
      margin-top: var(--lp-space-16);
    }

    .payment-note {
      color: var(--lp-text-tertiary);
    }

    /* ========================================
       BILLING MODAL
       ======================================== */

    /* ========================================
       UPGRADE / PAYMENT MODAL
       ======================================== */
    
    .upgrade-body {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-16);
    }
    
    .upgrade-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: var(--lp-space-12);
    }
    
    .upgrade-card {
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      background: var(--lp-bg-base);
      display: flex;
      flex-direction: column;
    }
    
    .upgrade-card--current {
      border-color: var(--lp-stroke-strong);
    }
    
    .upgrade-card__plan {
      font-size: var(--lp-text-xl);
      font-weight: var(--lp-font-semibold);
      margin: var(--lp-space-8) 0;
    }
    
    .upgrade-card__price {
      font-size: var(--lp-text-2xl);
      font-weight: var(--lp-font-semibold);
      margin: var(--lp-space-8) 0;
    }
    
    .upgrade-card__price .text-label {
      font-size: var(--lp-text-base);
      font-weight: var(--lp-font-normal);
    }
    
    .upgrade-list {
      list-style: none;
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
      margin: var(--lp-space-12) 0;
      flex: 1;
    }
    
    .upgrade-card__cta {
      margin-top: auto;
      padding-top: var(--lp-space-12);
    }
    
    .payment-body {
      display: none;
      flex-direction: column;
      gap: var(--lp-space-16);
    }
    
    .payment-body--visible {
      display: flex;
    }
    
    .payment-summary {
      padding: var(--lp-space-16);
      border-radius: var(--lp-radius-m);
      background: var(--lp-bg-base);
    }
    
    .payment-row {
      display: flex;
      gap: var(--lp-space-12);
    }
    
    .payment-field {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
    }
    
    .payment-coupon-row {
      display: flex;
      gap: var(--lp-space-8);
      align-items: stretch;
    }
    
    .payment-coupon-row .input {
      flex: 1;
    }

    .settings-subsection__title {
      font-size: var(--lp-text-sm);
      font-weight: var(--lp-font-medium);
      color: var(--lp-text-tertiary);
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }
    
    /* Toggle switch */
    .toggle {
      position: relative;
      display: inline-block;
      width: 44px;
      height: 24px;
      flex-shrink: 0;
    }
    
    .toggle input {
      opacity: 0;
      width: 0;
      height: 0;
    }
    
    .toggle__slider {
      position: absolute;
      cursor: pointer;
      inset: 0;
      background: var(--lp-stroke-default);
      border-radius: var(--lp-radius-full);
      transition: background var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .toggle__slider::before {
      content: "";
      position: absolute;
      height: 18px;
      width: 18px;
      left: 3px;
      bottom: 3px;
      background: var(--lp-bg-surface);
      border-radius: 50%;
      transition: transform var(--lp-motion-fast) var(--lp-ease-out);
    }
    
    .toggle input:checked + .toggle__slider {
      background: var(--lp-accent-base);
    }
    
    .toggle input:checked + .toggle__slider::before {
      transform: translateX(20px);
    }
    
    .toggle input:focus-visible + .toggle__slider {
      box-shadow: var(--lp-focus-ring);
    }

    /* Responsive for new pages */
    @media (max-width: 768px) {
      .affiliate-product-layout,
      .affiliate-preview-layout {
        grid-template-columns: 1fr;
      }
      .affiliate-earnings-overview {
        grid-template-columns: repeat(2, 1fr);
      }
      .affiliate-steps {
        flex-direction: column;
      }
      .upgrade-grid {
        grid-template-columns: 1fr;
      }
      .ns-hero {
        min-height: 40vh;
      }
      .ns-hero__title {
        font-size: var(--lp-text-2xl);
      }
      
      /* Input bar mobile adjustments */
      .ns-input-bar {
        min-height: var(--lp-topbar-height);
        padding: var(--lp-space-8) var(--lp-space-12);
      }
      .ns-input-bar-shell {
        padding: var(--lp-space-16);
      }
      
      /* Bubble mobile adjustments - prevent scrollbar overlap */
      .bubble {
        max-width: calc(100% - var(--lp-space-16));
      }
      .bubble--user {
        max-width: calc(85% - var(--lp-space-16));
      }
      
      /* Popovers as bottom sheets on mobile */
      #notifications-popover,
      #account-popover {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        top: auto;
        width: 100%;
        max-width: 100%;
        max-height: 70vh;
        border-radius: var(--lp-radius-xl) var(--lp-radius-xl) 0 0;
        transform: translateY(100%);
      }
      
      #notifications-popover.popover--open,
      #account-popover.popover--open {
        transform: translateY(0);
      }

      /* The card and history menus were the last shape left: floating boxes anchored mid-screen with
         no handle (measured 2026-09-10: top 358, bottom 568, absolutely positioned). They are action
         lists like every other sheet, so they take the same shape here. */
      #kebab-popover,
      #history-kebab-popover,
      .kebab-menu--fixed {
        position: fixed;
        /* The anchoring script writes top/left/right inline to park the menu beside its card, and an
           inline top plus bottom:0 stretches a fixed element: four 44px rows filled 370px (measured
           2026-09-10). On a phone the menu is a bottom sheet, so the inline anchor has to go, and
           only !important outranks an inline style. */
        top: auto !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0;
        left: 0;
        right: 0;
        width: 100%;
        max-width: 100%;
        max-height: 70vh;
        /* Hug the items: the anchored version had a fixed height that left half a screen of empty
           sheet under four menu rows (measured 2026-09-10: 370px tall for 4 items). */
        height: auto;
        border-radius: var(--lp-radius-xl) var(--lp-radius-xl) 0 0;
        padding-bottom: env(safe-area-inset-bottom, 0px);
      }

      #kebab-popover::before,
      #history-kebab-popover::before,
      .kebab-menu--fixed::before {
        content: "";
        display: block;
        width: 36px;
        height: 5px;
        margin: var(--lp-space-8) auto var(--lp-space-16);
        border-radius: var(--lp-radius-full);
        background: var(--lp-stroke-strong);
        flex: none;
      }

      /* Same grab handle as .lp-sheet. Kenz, 2026-09-10: the Collections options sheet had the
         grey bar and these two did not, so the same gesture looked like two different surfaces.
         Drawn with a pseudo-element because these popovers are shared markup used as a dropdown
         on a wide screen, where no handle should appear. */

      /* REMOVED 2026-09-10: the phone compatibility layer that turned every `.modal` into a bottom
         sheet. It existed so sixteen components with their own markup could look like sheets while
         they were converted one at a time. All sixteen now render through LpSheet, so the layer had
         no users left; the only files still writing `.modal` are the unreachable /setting tree.
         Deleted with it: the drag classes, the loading-state override, the z-index lift over the
         close overlay and the full-height rule, all of which LpSheet carries itself. */

      /* The handle has to sit the same distance from the rim on every sheet. Measured 2026-09-10:
         9px on the shared sheet, 8px on a legacy modal, and 24px on the popovers, whose own 16px
         top padding pushed it down. Zero that padding and let the handle's own 8px place it. */
      #notifications-popover,
      #account-popover,
      #kebab-popover,
      #history-kebab-popover,
      .kebab-menu--fixed {
        padding-top: 0;
      }

      #notifications-popover::before,
      #account-popover::before {
        content: "";
        display: block;
        width: 36px;
        height: 5px;
        margin: var(--lp-space-8) auto var(--lp-space-16);
        border-radius: var(--lp-radius-full);
        background: var(--lp-stroke-strong);
        flex: none;
      }
      
      /* Ensure touch targets are at least 44px */
      .popover__item,
      .kebab-menu__item {
        min-height: var(--lp-height-lg);
      }
      
      /* History item touch target */
      .history-item {
        padding: var(--lp-space-12) var(--lp-space-16);
      }
    }

    /* ========================================
       TOUCH & HOVER FIXES — P1
       ======================================== */
    
    /* Touch action for faster taps (removes 300ms delay) */
    button, .btn, .nav-item, .filter-chip, .ns-hint, 
    .icon-btn, .kebab-btn, .link-button, .notif-item,
    .collections-row, .history-item, .app-card {
      touch-action: manipulation;
    }
    
    /* Expand touch targets for micro buttons */
    .btn--micro {
      position: relative;
    }
    
    .btn--micro::before {
      content: "";
      position: absolute;
      top: -8px;
      right: -4px;
      bottom: -8px;
      left: -4px;
    }
    
    /* Hover states only for devices that support hover */
    @media (hover: none) {
      /* Remove hover backgrounds on touch-only devices */
      .nav-item:hover,
      .filter-chip:hover,
      .ns-hint:hover,
      .collections-row:hover,
      .history-item:hover,
      .app-card:hover,
      .card:hover,
      .kebab-menu__item:hover,
      .popover__item:hover,
      .ns-mode-option:hover {
        background: inherit;
        border-color: inherit;
        box-shadow: inherit;
        transform: none; /* Prevent bounce on tap */
      }

      /* Hover-revealed actions always visible on touch (no hover affordance) */
      .card__actions {
        opacity: 1;
      }

      /* Use active state instead for touch feedback */
      .nav-item:active,
      .filter-chip:active,
      .ns-hint:active,
      .btn:active {
        opacity: 0.7;
        transition: opacity 0ms;
      }
    }
    
    /* Keyboard open state adjustments - instant, no bounce */
    .keyboard-open .ns-input-bar-shell {
      /* No transition - instant adjustment prevents bounce */
    }
    
    .keyboard-open .toast {
      /* No transition - instant adjustment */
    }

    /* ========================================
       AUTH MODAL
       ======================================== */
    
    /* The sign-up card is 863px tall (Google button + 4 fields + submit + mode switch). Measured
       2026-09-03 in chromium: at 390x667 it sat from y=-98 to y=765, so the title was cut off the
       top and the mode switch off the bottom, and because this backdrop centred with no overflow
       the user could not scroll to either. On a logged-out app that is the whole product behind an
       unreachable form. align-items:flex-start + margin:auto keeps the card centred when it fits
       and lets it scroll when it does not; overscroll-behavior stops the page behind it moving. */
    .auth-backdrop {
      position: fixed;
      inset: 0;
      background: var(--lp-overlay-darker);
      display: flex;
      align-items: flex-start;
      justify-content: center;
      overflow-y: auto;
      overscroll-behavior: contain;
      padding: var(--lp-space-16) 0;
      z-index: var(--lp-z-top);
      opacity: 1;
      transition: opacity var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    .auth-backdrop--hidden {
      opacity: 0;
      pointer-events: none;
    }
    
    .auth-modal {
      width: 400px;
      max-width: 96vw;
      background: var(--lp-bg-surface);
      border-radius: var(--lp-radius-xl);
      border: var(--lp-border-thin) solid var(--lp-stroke-default);
      box-shadow: var(--lp-shadow-l);
      padding: var(--lp-space-24);
      margin: auto;
      animation: auth-modal-enter var(--lp-motion-mid) var(--lp-ease-out);
    }
    
    @keyframes auth-modal-enter {
      from { transform: translateY(20px); opacity: 0; }
      to { transform: translateY(0); opacity: 1; }
    }
    
    .auth-modal__header {
      text-align: center;
      margin-bottom: var(--lp-space-24);
    }
    
    .auth-modal__logo {
      width: 48px;
      height: 48px;
      margin: 0 auto var(--lp-space-16);
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .auth-modal__logo svg {
      width: 100%;
      height: 100%;
    }
    
    .auth-modal__title {
      font-size: var(--lp-text-xl);
      font-weight: var(--lp-font-semibold);
      color: var(--lp-text-primary);
      margin-bottom: var(--lp-space-4);
    }
    
    .auth-modal__subtitle {
      font-size: var(--lp-text-base);
      color: var(--lp-text-secondary);
    }
    
    .auth-provider {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-8);
      margin-bottom: var(--lp-space-16);
    }
    
    .auth-provider .btn {
      width: 100%;
      height: var(--lp-height-md);
    }
    
    .provider-icon {
      width: var(--lp-size-4);
      height: var(--lp-size-4);
      border-radius: var(--lp-radius-full);
      border: 1.5px solid currentColor;
    }
    
    .auth-divider {
      display: flex;
      align-items: center;
      gap: var(--lp-space-8);
      font-size: var(--lp-text-sm);
      color: var(--lp-text-tertiary);
      margin-bottom: var(--lp-space-16);
    }
    
    .auth-divider::before,
    .auth-divider::after {
      content: "";
      flex: 1;
      height: 1px;
      background: var(--lp-stroke-default);
    }
    
    .auth-form {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-12);
    }
    
    .auth-form .field-group {
      display: flex;
      flex-direction: column;
      gap: var(--lp-space-4);
    }
    
    .auth-form .field-label {
      font-size: var(--lp-text-sm);
      color: var(--lp-text-secondary);
    }
    
    .auth-form .btn--primary {
      width: 100%;
      height: var(--lp-height-md);
      margin-top: var(--lp-space-8);
    }
    
    .auth-footer {
      margin-top: var(--lp-space-16);
      text-align: center;
    }
    
    .auth-footer .btn--tertiary {
      font-size: var(--lp-text-sm);
    }
    
    /* The wall covers the whole logged-out app and had no visible way out; its siblings
       (forgot / reset / verify) all offer "Back to sign in", so the gate itself was the only
       screen with no exit. One tertiary link, below the mode switch and above the legal line, so
       it never competes with the primary action. Floor: an exit must be visible, not merely
       reachable through the browser's Back button. */
    .auth-exit {
      margin-top: var(--lp-space-12);
      text-align: center;
      font-size: var(--lp-text-xs);
    }

    .auth-exit a {
      color: var(--lp-text-tertiary);
      text-decoration: none;
    }

    .auth-exit a:hover {
      color: var(--lp-text-secondary);
      text-decoration: underline;
    }

    .auth-legal {
      margin-top: var(--lp-space-16);
      font-size: var(--lp-text-xs);
      color: var(--lp-text-tertiary);
      text-align: center;
      line-height: var(--lp-leading-snug);
    }
    
    .auth-legal a {
      color: inherit;
      text-decoration: underline;
    }

    /* Auth: Verify email state */
    .auth-verify { display: flex; flex-direction: column; align-items: center; text-align: center; }
    /* Holds an SVG drawn with currentColor, so the bar is the 3:1 of SC 1.4.11
       rather than 4.5, and the accent measured 2.84:1 on this tint, under even
       that. The text accent clears it without touching the tint. */
    .auth-verify__icon { width: 56px; height: 56px; border-radius: var(--lp-radius-full); background: var(--lp-overlay-accent); color: var(--lp-accent-text); display: flex; align-items: center; justify-content: center; margin-bottom: var(--lp-space-16); }
    .auth-verify__title { font-size: var(--lp-text-xl); font-weight: var(--lp-font-semibold); color: var(--lp-text-primary); margin-bottom: var(--lp-space-16); }
    .auth-verify__email-chip { font-size: var(--lp-text-base); font-weight: var(--lp-font-medium); color: var(--lp-text-primary); background: var(--lp-wash-strong); border: var(--lp-border-thin) solid var(--lp-stroke-default); border-radius: var(--lp-radius-full); padding: var(--lp-space-8) var(--lp-space-16); margin-bottom: var(--lp-space-12); }
    .auth-verify__hint { font-size: var(--lp-text-sm); color: var(--lp-text-tertiary); line-height: var(--lp-leading-relaxed); margin-bottom: var(--lp-space-24); }
    .auth-verify__resend { width: 100%; height: var(--lp-height-md); margin-bottom: var(--lp-space-8); }
    .auth-verify__resend:disabled { opacity: var(--lp-opacity-disabled); cursor: not-allowed; }
    .auth-verify__back { font-size: var(--lp-text-sm); }

    /* Auth: Forgot password link */
    .auth-forgot-link { text-align: right; margin-top: -4px; }

    /* Team: Member view */
    
    .field-error {
      font-size: var(--lp-text-xs);
      color: var(--lp-error-text);
      margin-top: var(--lp-space-4);
      display: none;
    }
    
    .field-error--visible {
      display: block;
    }

    /* ========================================
       TOUCH TAP TARGETS (mobile only)
       44px minimum for fingers, WCAG 2.5.5 / Apple HIG.
       Desktop keeps the compact sizes above.
       ======================================== */
    @media (max-width: 768px) {
      .icon-btn,
      .search-trigger,
      .modal__close,
      .ns-send-circle,
      .password-toggle-btn {
        min-width: 44px;
        min-height: 44px;
      }

      .btn,
      .btn--sm,
      .ns-hint,
      .ns-mode-addon,
      .nav-item {
        min-height: 44px;
      }

      /* keep the eye toggle inside the password field */
      .input--password > .input {
        padding-right: 48px;
      }

      /* 2026-09-06. Measured on the signed-in demo at 390px: three more targets sat
         under the finger bar that the list above never named. They are the whole class
         of controls declared at ICON size or at TEXT size and never re-sized for touch,
         so all four siblings are listed, not only the two the run happened to sample.
         .card__action-btn shares its base rule with .spotlight-qa-btn; both are 24px on
         desktop and stay 24px there, this only widens them where fingers are. */
      .spotlight-qa-btn,
      .card__action-btn,
      .link-button,
      .link-button--sm {
        min-width: 44px;
        min-height: 44px;
      }

      /* A text button is as wide as its word, so "Copy" and "Save" under a reply measured 30x44 at 320
         (demo/grammar-walk.mjs): the width floor above now covers it, the label stays centred in it. */
      .link-button,
      .link-button--sm {
        display: inline-flex;
        align-items: center;
        justify-content: center;
      }
    }

/* ==========================================================================
   SHEET KIT (2026-09-10, Collections redesign v1 approved by Kenz)
   One pattern for every secondary surface: a bottom sheet on a phone, a centred dialog or an
   anchored popover from 768px. Composed only from existing tokens.
   ========================================================================== */
.lp-scrim{position:fixed;inset:0;z-index:1000;background:var(--lp-overlay-dark);opacity:0;pointer-events:none;transition:opacity var(--lp-motion-slow) var(--lp-ease-out)}
.lp-scrim--on{opacity:1;pointer-events:auto}
.lp-sheet{position:fixed;left:0;right:0;bottom:0;z-index:1001;max-height:88vh;overflow:auto;overscroll-behavior:contain;background:var(--lp-bg-surface);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-bottom:0;border-top-left-radius:var(--lp-radius-xl);border-top-right-radius:var(--lp-radius-xl);box-shadow:var(--lp-shadow-l);padding:0 var(--lp-space-20) calc(var(--lp-space-24) + env(safe-area-inset-bottom));transform:translateY(100%);visibility:hidden;transition:transform var(--lp-motion-slow) var(--lp-ease-out),visibility 0s linear var(--lp-motion-slow)}
.lp-sheet--on{transform:none;visibility:visible;transition:transform var(--lp-motion-slow) var(--lp-ease-out)}
.lp-sheet:focus{outline:none}
/* A dialog's heading takes focus when the dialog opens (public/lp-overlay.js, 27/09), so a screen reader names
   what opened. It is not a control and never draws a ring; Tab moves on to the first control. */
h1[tabindex="-1"]:focus,h2[tabindex="-1"]:focus,h3[tabindex="-1"]:focus{outline:none}
/* 2026-09-10, Kenz: "sao sát mép trên vậy?" The title sat 18px from the sheet edge and 4px
   under the handle, so it read as if it were crowding the rim. The handle needs air under it, the
   same 16 that separates the title from the body. */
.lp-sheet__grabzone{display:block;width:100%;padding:var(--lp-space-8) 0 var(--lp-space-16);margin:0;border:0;background:transparent;touch-action:none;cursor:grab}
.lp-sheet__grabzone:focus-visible{outline:none;box-shadow:var(--lp-focus-ring);border-radius:var(--lp-radius-m)}
.lp-sheet--dragging{transition:none}
@media (min-width:768px){.lp-sheet__grabzone{display:none}}
.lp-sheet__grab{width:36px;height:5px;border-radius:var(--lp-radius-full);background:var(--lp-stroke-strong);margin:0 auto}
/* A sheet that declares a header becomes a column: header fixed, body scrolls. Without the header
   slot nothing changes, so the short sheets keep scrolling as one piece. */
.lp-sheet:has(.lp-sheet__head){display:flex;flex-direction:column;overflow:hidden}
.lp-sheet__head{flex:none;padding-bottom:var(--lp-space-20)}
.lp-sheet--stacked{z-index:1003}
.lp-scrim--stacked{z-index:1002}
.lp-sheet__foot{flex:none}
.lp-sheet:has(.lp-sheet__foot){display:flex;flex-direction:column;overflow:hidden}
/* A sheet scrolls to its own edge (approved 2026-09-23, design system 10.x). The scroll region
   carries the side padding, not the sheet around it, so the scrollbar sits flush with the sheet's
   border while the text keeps its inset. Before: the sheet held 20px and the scroller ran 20px in
   from the edge. Only column sheets (head or foot) are affected; a short sheet without either
   still scrolls as one piece with its own padding. */
.lp-sheet:has(.lp-sheet__head),.lp-sheet:has(.lp-sheet__foot){padding-left:0;padding-right:0;padding-bottom:0}
.lp-sheet__head,.lp-sheet__foot,.lp-sheet__scroll{padding-left:var(--lp-sheet-pad,var(--lp-space-20));padding-right:var(--lp-sheet-pad,var(--lp-space-20))}
.lp-sheet__foot{padding-bottom:calc(var(--lp-space-24) + env(safe-area-inset-bottom))}
.lp-sheet:has(.lp-sheet__head):not(:has(.lp-sheet__foot)) .lp-sheet__scroll{padding-bottom:calc(var(--lp-space-24) + env(safe-area-inset-bottom))}
.lp-sheet--full{max-height:calc(100vh - var(--lp-space-8));max-height:calc(100dvh - var(--lp-space-8))}
.lp-sheet__scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.lp-sheet__title{font-size:var(--lp-text-xl-plus);font-weight:var(--lp-font-semibold);letter-spacing:-.01em;line-height:1.35;margin:0 0 var(--lp-space-16);color:var(--lp-text-primary)}
/* 2026-09-10, Kenz on the converted notification sheet: "sao nó xấu, sát rịt nhau vậy?" Measured
   then: 20px title, 4px gap, 15px heading, a NEGATIVE 4px on the meta line, 13px body 8px below, and
   a 13px button. Four sizes inside 8px of each other is no hierarchy, and 4px gaps read as one
   block. This gives the sheet body the same rhythm as the rest of the app: one step per level, and
   space proportional to the break between them. */
.lp-sheet__body{margin:var(--lp-space-20) 0 var(--lp-space-32)}
.lp-sheet__body > * + *{margin-top:var(--lp-space-16)}
.lp-sheet__body .text-heading{font-size:var(--lp-text-xl);font-weight:var(--lp-font-semibold);line-height:1.35;color:var(--lp-text-primary);margin:0}
.lp-sheet__meta{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);margin:var(--lp-space-4) 0 0}
.lp-sheet__body .text-body{font-size:var(--lp-text-lg);line-height:1.65;color:var(--lp-text-secondary)}
.lp-sheet__body .text-body p{margin:0 0 var(--lp-space-12)}
.lp-sheet__body .text-body p:last-child{margin-bottom:0}
/* A read-only sheet has nothing to commit, so its way out should not look like the loudest action
   on screen: a full-width accent button under three lines of text is what made this read cramped
   (Kenz's screenshot, 2026-09-10). Quiet, and given room above it. */
/* 2026-09-10, Kenz on the prompt editor: "mấy cái title của form nó sát mấy dòng trên quá ta?"
   Measured: label to its own input 8px, which is right, but one group to the next 0px, so every
   label sat against the field above it and the form read as one undifferentiated column. A label
   belongs to what follows it, so the space goes between the groups, not inside them. */
.lp-sheet .field-group + .field-group,
.lp-sheet__body .field-group + .field-group{margin-top:var(--lp-space-20)}
.lp-sheet .editor-meta-row,
.lp-sheet .field-row{gap:var(--lp-space-20)}
.lp-sheet .editor-meta-row .field-group + .field-group,
.lp-sheet .field-row .field-group + .field-group,
.lp-sheet__body .field-row .field-group + .field-group{margin-top:0}
.lp-sheet .editor-meta-row + *,
.lp-sheet * + .editor-meta-row{margin-top:var(--lp-space-20)}
.lp-sheet__titlerow{display:flex;align-items:center;gap:var(--lp-space-8)}
.lp-sheet__titlerow .lp-sheet__title{margin-bottom:0}
.lp-sheet__fineprint{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
@media (max-width:767px){
  .lp-sheet__footer--actions{flex-direction:column-reverse;align-items:stretch;text-align:center}
  .lp-sheet__footer--actions .lp-sheet__actions{width:100%}
  /* A lone action in the footer takes the width too, the same as a pair does. Measured 2026-09-10:
     after the upgrade sheet moved onto this class its Start lifetime button shrank to a pill. */
  .lp-sheet__footer--actions > .btn{width:100%}
}
.lp-sheet__footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--lp-space-16);margin-top:var(--lp-space-24)}
.lp-sheet__legal{display:flex;flex-wrap:wrap;align-items:center;gap:var(--lp-space-8);font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.lp-sheet__legal a{color:var(--lp-text-tertiary);text-decoration:none;position:relative}
/* The hit area is drawn by this pseudo-element, so the SHORTEST label decides whether the
   row passes: measured 2026-09-21 on the settings sheet, "Terms" renders 35.34px wide and
   -4px a side made it 43, one pixel under the 44 the audit requires, while every other
   label cleared it. -8px gives the shortest label 51 and still leaves 3.9px between
   neighbouring hit areas at the measured 19.9px spacing, so no two of them overlap. */
.lp-sheet__legal a::before{content:"";position:absolute;inset:-15px -8px}
.lp-sheet__legal a:hover{color:var(--lp-text-secondary)}
/* Buttons that sit together in a footer are one set, so they take one width: a lone Close keeps its
   120px minimum, but next to a sibling both are sized by the WIDER of the two. Measured 2026-09-10 on
   the Referrals sheet: Close 120 beside Download 92, because the lone-close class was applied to a
   button that has a sibling. Sizing by the set rather than by the class removes the whole question. */
.lp-sheet__footer .lp-sheet__done{width:auto;min-width:120px}
.lp-sheet__footer--actions{justify-content:flex-end}
.lp-sheet__footer--actions > .lp-sheet__fineprint,
.lp-sheet__footer--actions > .lp-sheet__legal{margin-right:auto}
.lp-sheet__footer--actions .btn,
.lp-sheet__footer .btn{min-width:120px;min-height:var(--lp-height-lg);font-size:var(--lp-text-lg);font-weight:var(--lp-font-medium)}
.lp-sheet__actions{display:flex;gap:var(--lp-space-8)}
.lp-sheet__actions .btn{flex:1 1 0;min-width:120px}
@media (max-width:767px){.lp-sheet__footer .lp-sheet__done{width:100%}}
.lp-sheet__done{width:100%;min-height:var(--lp-height-lg);font-size:var(--lp-text-lg);font-weight:var(--lp-font-medium);
  background:transparent;color:var(--lp-text-secondary);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-full)}
.lp-sheet__done:hover{background:var(--lp-bg-elevated);color:var(--lp-text-primary)}
/* A caption belongs to the title above it, but belonging is not touching: pulling it up with a
   negative margin left ZERO measured gap between the two boxes and 4px of overlap in the margin
   (Kenz, 2026-09-10). The title simply stops claiming space below it when a caption follows, and the
   caption takes a 6px step of its own. */
.lp-sheet__title:has(+ .lp-sheet__sub),
.lp-sheet__title:has(+ .lp-sheet__meta){margin-bottom:0}
.lp-sheet__title + .lp-sheet__sub,
.lp-sheet__title + .lp-sheet__meta{margin-top:var(--lp-space-4)}
.lp-sheet__sub{font-size:var(--lp-text-md);color:var(--lp-text-secondary);margin:0 0 var(--lp-space-16)}
@media (min-width:768px){
  .lp-sheet{left:50%;right:auto;bottom:auto;top:50%;width:var(--lp-sheet-w,520px);max-width:calc(100vw - var(--lp-space-32));max-height:80vh;border-radius:var(--lp-radius-xl);border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default);padding:var(--lp-space-20);transform:translate(-50%,-48%) scale(.98);opacity:0}
  .lp-sheet--on{transform:translate(-50%,-50%);opacity:1;transition:transform var(--lp-motion-slow) var(--lp-ease-out),opacity var(--lp-motion-slow) var(--lp-ease-out)}
  .lp-sheet__grab{display:none}
  .lp-sheet--sm{--lp-sheet-w:400px}
  .lp-sheet--md{--lp-sheet-w:520px}
  .lp-sheet--lg{--lp-sheet-w:var(--lp-modal-lg)}
  /* Expand (approved 2026-09-23): the prompt editor grows to most of the window on request. */
  .lp-sheet--xl{--lp-sheet-w:min(960px,calc(100vw - 64px));max-height:calc(100vh - 48px)}
  .lp-sheet:has(.lp-sheet__head),.lp-sheet:has(.lp-sheet__foot){padding:0}
  .lp-sheet__head{padding-top:var(--lp-space-20)}
  .lp-sheet__foot{padding-bottom:var(--lp-space-20)}
  .lp-sheet:has(.lp-sheet__head):not(:has(.lp-sheet__foot)) .lp-sheet__scroll{padding-bottom:var(--lp-space-20)}
  .lp-sheet:has(.lp-sheet__foot):not(:has(.lp-sheet__head)) .lp-sheet__scroll{padding-top:var(--lp-space-20)}
}
.lp-field{width:100%;min-height:44px;border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);background:var(--lp-bg-input);color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-lg);padding:0 var(--lp-space-12)}
.lp-field:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.lp-touch{position:relative;min-width:44px;min-height:44px;display:inline-grid;place-items:center;border-radius:var(--lp-radius-full);background:transparent;border:0;color:var(--lp-text-secondary);cursor:pointer;transition:background var(--lp-motion-mid) var(--lp-ease-out)}
.lp-touch:hover{background:var(--lp-wash-hover)} .lp-touch:active{background:var(--lp-wash-active)}
.lp-touch:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.lp-touch--filled{background:var(--lp-bg-surface);color:var(--lp-text-primary)}
.lp-touch svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.content-header__actions{display:flex;align-items:center;gap:var(--lp-space-8)}
@media (prefers-reduced-motion:reduce){:root:not([data-lp-reduce-motion="off"]) .lp-scrim,:root:not([data-lp-reduce-motion="off"]) .lp-sheet,:root:not([data-lp-reduce-motion="off"]) .lp-sheet--on{transition-duration:0ms}}

/* ==========================================================================
   COLLECTIONS v1 (approved 2026-09-10): the page itself, matched to
   kenz-runtime-preview docs/design/collections-redesign-v1.html. Scoped to the page so
   History and Apps keep their current look until they get their own pass.
   ========================================================================== */
.page[data-page="collections"] .content-header{flex-wrap:nowrap;align-items:center;margin-bottom:var(--lp-space-16)}
.page[data-page="collections"] .content-header__title{flex:1;min-width:0}
/* 2026-09-23 (Kenz: "Collections dùng shell riêng?"): the page title is the shell's, 18px like every other page,
   as the 23/09 canvas draws it; the 28px override from the 10/09 pass is gone. Header actions are 32px on a
   desktop like the Session's New, 44px on a phone. */
@media (min-width:768px){
  .page[data-page="collections"] .cx-new{min-height:32px;padding:0 var(--lp-space-12) 0 var(--lp-space-8);font-size:var(--lp-text-sm)}
  .page[data-page="collections"] .cx-new svg{width:16px;height:16px}
  .page[data-page="collections"] .content-header .lp-touch{width:32px;height:32px;min-width:32px;min-height:32px}
}
.page[data-page="collections"] .cx-new{display:inline-flex;align-items:center;gap:var(--lp-space-8);min-height:44px;padding:0 var(--lp-space-16) 0 var(--lp-space-12);font-size:var(--lp-text-md);font-weight:var(--lp-font-semibold)}
.page[data-page="collections"] .cx-new svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}
.page[data-page="collections"] .filter-row{flex-wrap:nowrap;margin:0 calc(var(--lp-space-16) * -1) var(--lp-space-20);border:0}
.page[data-page="collections"] .filter-tabs{scroll-padding-inline:var(--lp-space-16);gap:var(--lp-space-8);padding:var(--lp-space-4) var(--lp-space-16);scroll-snap-type:x proximity}
.page[data-page="collections"] .filter-divider{display:none}
.page[data-page="collections"] .filter-chip{flex:none;scroll-snap-align:start;margin:0;min-height:36px;min-width:0;padding:0 var(--lp-space-12);gap:var(--lp-space-8);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-secondary);font-size:var(--lp-text-md);font-weight:var(--lp-font-medium);white-space:nowrap;transition:background var(--lp-motion-mid) var(--lp-ease-out),color var(--lp-motion-mid) var(--lp-ease-out),border-color var(--lp-motion-mid) var(--lp-ease-out)}
.page[data-page="collections"] .filter-chip::before{content:"";position:absolute;inset:-4px 0}
.page[data-page="collections"] .filter-chip{position:relative}
.page[data-page="collections"] .filter-chip__count{color:var(--lp-text-tertiary);font-size:var(--lp-text-sm);font-variant-numeric:tabular-nums}
.page[data-page="collections"] .filter-chip--active{background:var(--lp-text-primary);border-color:var(--lp-text-primary);color:var(--lp-bg-base)}
.page[data-page="collections"] .filter-chip--active .filter-chip__count{color:inherit;opacity:.7}
.page[data-page="collections"] .filter-chip:focus-visible{border-radius:var(--lp-radius-full)}
.page[data-page="collections"] .collections-grid{grid-template-columns:1fr;gap:var(--lp-space-12)}
@media (min-width:640px){.page[data-page="collections"] .collections-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:992px){.page[data-page="collections"] .collections-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
.page[data-page="collections"] .card{max-width:none;display:flex;flex-direction:column;gap:var(--lp-space-4);min-height:112px;padding:var(--lp-space-16);background:var(--lp-bg-surface);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-l);box-shadow:none;transform:none;transition:border-color var(--lp-motion-mid) var(--lp-ease-out)}
.page[data-page="collections"] .card:hover{border-color:var(--lp-stroke-strong);box-shadow:none;transform:none}
.page[data-page="collections"] .card:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.page[data-page="collections"] .card__top{align-items:flex-start;gap:var(--lp-space-8)}
.page[data-page="collections"] .card__title{flex:1;min-width:0;font-size:var(--lp-text-lg-plus);font-weight:var(--lp-font-semibold);line-height:1.35}
.page[data-page="collections"] .card__preview{font-size:var(--lp-text-md);line-height:1.5;color:var(--lp-text-secondary);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;white-space:normal}
.page[data-page="collections"] .card__meta{margin-top:auto;padding-top:var(--lp-space-8);font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.page[data-page="collections"] .card__actions{opacity:1;margin:calc(var(--lp-space-12) * -1) calc(var(--lp-space-12) * -1) 0 0;gap:0}
.page[data-page="collections"] .card__action-btn{width:44px;height:44px;border-radius:var(--lp-radius-full);color:var(--lp-text-tertiary)}
.page[data-page="collections"] .card__action-btn svg{width:18px;height:18px}
.page[data-page="collections"] .card__action-btn--desk{display:none}
@media (hover:hover) and (pointer:fine){
  .page[data-page="collections"] .card__action-btn--desk{display:grid;opacity:0;transition:opacity var(--lp-motion-mid) var(--lp-ease-out)}
  .page[data-page="collections"] .card:hover .card__action-btn--desk,.page[data-page="collections"] .card:focus-within .card__action-btn--desk{opacity:1}
}

/* Switch and popover (phase 2, Collections v1; the options rows became L1 rows 2026-09-25) */
.lp-switch{position:relative;flex:none;width:51px;height:31px;border-radius:var(--lp-radius-full);background:var(--lp-bg-elevated);border:var(--lp-border-thin) solid var(--lp-stroke-default);transition:background var(--lp-motion-slow) var(--lp-ease-out)}
.lp-switch::after{content:"";position:absolute;top:2px;left:2px;width:25px;height:25px;border-radius:50%;background:#FFFFFF;box-shadow:var(--lp-shadow-s);transition:transform var(--lp-motion-slow) var(--lp-ease-out)}
.lp-switch[aria-checked="true"]{background:var(--lp-success);border-color:var(--lp-success)}
.lp-switch[aria-checked="true"]::after{transform:translateX(20px)}
button.lp-switch{padding:0;cursor:pointer}
button.lp-switch:disabled{opacity:.45;cursor:not-allowed}
button.lp-switch:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
@media (min-width:768px){
  .lp-sheet--pop{bottom:auto;right:auto;width:320px;padding:var(--lp-space-8);transform:translateY(-4px)}
  .lp-sheet--pop.lp-sheet--on{transform:none}
  .lp-scrim--clear{background:transparent}
}
.page[data-page="collections"] .filter-chip--starters svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linejoin:round}
.page[data-page="collections"] .cx-lead{color:var(--lp-text-tertiary);font-size:var(--lp-text-md);margin:calc(var(--lp-space-8) * -1) 0 var(--lp-space-16)}
.page[data-page="collections"] .cx-starter-meta{display:flex;align-items:center;gap:var(--lp-space-8)}
.page[data-page="collections"] .cx-save{margin-left:auto;display:inline-flex;align-items:center;gap:var(--lp-space-8);min-height:36px;padding:0 var(--lp-space-12);border-radius:var(--lp-radius-full);border:var(--lp-border-thin) solid var(--lp-stroke-default);background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base);font-weight:var(--lp-font-medium);cursor:pointer;position:relative}
.page[data-page="collections"] .cx-save::before{content:"";position:absolute;inset:-4px 0}
.page[data-page="collections"] .cx-save svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.page[data-page="collections"] .cx-save--done{color:var(--lp-text-secondary)}

/* Tidy up preview (phase 3, Collections v1). One line per collection: what it is called and how
   many prompts land there. Tags read as the app writes them everywhere else: the name in its own
   colour, no hash. */
.tidy-list{list-style:none;margin:0 0 var(--lp-space-16);padding:0}
.tidy-line{display:flex;align-items:center;gap:var(--lp-space-12);width:100%;min-height:48px;padding:0;border:0;border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default);background:transparent;font:inherit;text-align:left;cursor:pointer}
.tidy-line:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.tidy-line__chev{width:16px;height:16px;flex:none;stroke:var(--lp-text-tertiary);fill:none;stroke-width:1.75;stroke-linecap:round;transition:transform var(--lp-motion-mid) var(--lp-ease-out)}
.tidy-line__chev--open{transform:rotate(180deg)}
.tidy-inner{list-style:none;margin:0;padding:0 0 var(--lp-space-8) 30px;border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default)}
.tidy-inner__item{font-size:var(--lp-text-md);color:var(--lp-text-secondary);padding:2px 0}
.tidy-inner__from{color:var(--lp-text-tertiary)}
.tidy-list > li:last-child .tidy-line, .tidy-list > li:last-child .tidy-inner{border-bottom:0}
.tidy-line__icon{width:18px;height:18px;flex:none;stroke:var(--lp-text-tertiary);fill:none;stroke-width:1.75;stroke-linejoin:round}
.tidy-line__name{flex:1;min-width:0;font-size:var(--lp-text-lg);font-weight:var(--lp-font-medium);color:var(--lp-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tidy-line__count{color:var(--lp-text-tertiary);font-size:var(--lp-text-md);font-variant-numeric:tabular-nums}
.tidy-tagline{font-size:var(--lp-text-md);color:var(--lp-text-tertiary);margin:0 0 var(--lp-space-20)}
.tidy-tagname{font-weight:var(--lp-font-medium)}
.tidy-actions{display:grid;gap:var(--lp-space-8)}
.tidy-apply{width:100%;min-height:48px;font-size:var(--lp-text-lg-plus);font-weight:var(--lp-font-semibold)}
.tidy-quiet{min-height:48px;border:0;border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-secondary);font:inherit;font-weight:var(--lp-font-medium);cursor:pointer}
.tidy-quiet:hover{background:var(--lp-wash-hover)}
.tidy-fine{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);text-align:center;margin:var(--lp-space-8) 0 0}

/* ==========================================================================
   MANAGE SHEET (2026-09-10): one list pattern for the sheets that manage a set the customer owns.
   Collections and tags both use it, so it lives here rather than scoped inside one component.
   ========================================================================== */
.manage-search { margin-bottom: var(--lp-space-12); }
.manage-list { list-style: none; margin: 0 0 var(--lp-space-16); padding: 0; border: var(--lp-border-thin) solid var(--lp-stroke-default); border-radius: var(--lp-radius-m); overflow: hidden; background: var(--lp-bg-surface); }
.manage-item { border-bottom: var(--lp-border-thin) solid var(--lp-stroke-default); background: var(--lp-bg-surface); touch-action: none; }
.manage-item:last-child { border-bottom: 0; }
.manage-item--drag { position: relative; z-index: 2; box-shadow: var(--lp-shadow-m); border-radius: var(--lp-radius-m); }
.manage-row { display: flex; align-items: center; min-height: 52px; padding: 0 var(--lp-space-4); }
.manage-grip { color: var(--lp-text-tertiary); cursor: grab; }
.manage-name { flex: 1; min-width: 0; min-height: 44px; padding: 0 var(--lp-space-8); border: 0; background: transparent; color: var(--lp-text-primary); font: inherit; font-size: var(--lp-text-lg); font-weight: var(--lp-font-medium); text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: var(--lp-radius-s); cursor: text; }
.manage-name--edit { background: var(--lp-bg-input); box-shadow: var(--lp-focus-ring); }
.manage-count { color: var(--lp-text-tertiary); font-size: var(--lp-text-sm); font-variant-numeric: tabular-nums; padding: 0 var(--lp-space-4); }
.manage-more { color: var(--lp-text-tertiary); }
.manage-add { display: flex; align-items: center; gap: var(--lp-space-8); width: 100%; min-height: 52px; padding: 0 var(--lp-space-12); border: 0; background: transparent; color: var(--lp-text-primary); font: inherit; font-size: var(--lp-text-lg); font-weight: var(--lp-font-medium); text-align: left; cursor: pointer; }
.manage-add:hover { background: var(--lp-wash-hover); }
.manage-add__icon { width: 28px; height: 28px; display: grid; place-items: center; }
.manage-add__icon svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }

/* The library's Tools menu: the shared popover grammar at the width three verbs need. 2026-09-18. */
.library-tools-menu{width:200px;padding:var(--lp-space-8) 0}
.library-tools-menu .popover__item{display:block;width:100%;padding:10px var(--lp-space-16);
  font-size:var(--lp-text-base);color:var(--lp-text-primary);cursor:pointer;text-align:left}
.library-tools-menu .popover__item:hover{background:var(--lp-bg-elevated)}
.library-tools-menu .popover__item--busy{opacity:.6;cursor:default}

/* A glyph inside a button, sized to the label beside it. 2026-09-18. */
.btn__icon{width:18px;height:18px;flex:none}

/* Every control starts from nothing: a button that forgets to set a background falls back to
   transparent, not to the browser's own button face. 2026-09-18. */
button {
  appearance: none;
  background: transparent;
  border: none;
  color: inherit;
  font: inherit;
}

/* THE SHARED SHELL's account control (lp-ssot design system section 10, 2026-09-22): a round
   initial, byte-identical in the web app and both panels. */
.lp-avatar { width: 32px; height: 32px; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--lp-bg-elevated); color: var(--lp-text-primary); font-size: 12px; font-weight: 600; }

/* ==========================================================================
   GET STARTED (canvas boards StartDesktop / StartPhone / StartPhoneSheet, approved by Kenz
   2026-09-22). Composed only from existing tokens; no new colour, size or radius enters the
   system for this screen. The sheet itself is SHEET KIT above, unchanged.
   ========================================================================== */

/* The entry. One component, two placements: the sidebar card on a desktop, the same card under
   the top bar on a phone, because a phone has no sidebar on screen to put it in. */
.gs-entry{display:flex;flex-direction:column;gap:var(--lp-space-8);width:100%;box-sizing:border-box;
  padding:var(--lp-space-12);border:var(--lp-border-thin) solid var(--lp-stroke-default);
  border-radius:var(--lp-radius-m);background:var(--lp-bg-surface);cursor:pointer;text-align:left;
  transition:border-color var(--lp-motion-mid) var(--lp-ease-out)}
.gs-entry:hover{border-color:var(--lp-stroke-light)}
.gs-entry:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.gs-entry__row{display:flex;align-items:center;gap:var(--lp-space-8);font-size:var(--lp-text-base);color:var(--lp-text-primary)}
.gs-entry__icon{width:var(--lp-icon-base);height:var(--lp-icon-base);flex:none;fill:none;stroke:currentColor;
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.gs-entry__label{flex-grow:1;min-width:0}
.gs-entry__count{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.gs-entry__chev{width:var(--lp-icon-sm);height:var(--lp-icon-sm);flex:none;fill:none;stroke:var(--lp-text-tertiary);
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}

/* The bar is neutral, not accent: the screen's one accent belongs to the next step's button, and
   a second pink stripe beside it would split the eye. */
.gs-progress__track{display:block;height:4px;border-radius:var(--lp-radius-xs);background:var(--lp-bg-elevated);overflow:hidden}
.gs-progress__fill{display:block;height:4px;border-radius:var(--lp-radius-xs);background:var(--lp-text-secondary);
  transition:width var(--lp-motion-slow) var(--lp-ease-out)}
.gs-progress{display:flex;align-items:center;gap:var(--lp-space-12)}
.gs-progress .gs-progress__track{flex-grow:1}
.gs-progress__count{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);white-space:nowrap}

/* Which placement is on screen is decided here, once, so neither component has to know the width.
   A collapsed rail hides the entry with the rest of its labels rather than clipping it. */
.gs-entry--banner{display:none}
.gs-entry--sidebar{margin-bottom:var(--lp-space-8)}
.sidebar--collapsed .gs-entry--sidebar{display:none}
@media (max-width:767px){
  .gs-entry--sidebar{display:none}
  .gs-entry--banner{display:flex;width:auto;margin:0 var(--lp-space-16) var(--lp-space-4);min-height:var(--lp-height-lg)}
}

/* The sheet's own head: title, one line of why, then the same bar. */
.gs-sheet__title{margin-bottom:var(--lp-space-8)}
.gs-sheet__sub{margin:0;font-size:var(--lp-text-base);line-height:var(--lp-leading-normal);color:var(--lp-text-secondary)}
.gs-progress--sheet{margin-top:var(--lp-space-16)}

/* The steps. A rule above each row rather than around each one: five bordered cards inside a
   bordered sheet is four frames deep, and the list reads as a list without them. */
.gs-steps{list-style:none;margin:0;padding:0}
.gs-step{display:flex;align-items:center;gap:var(--lp-space-12);padding:14px 0;
  border-top:var(--lp-border-thin) solid var(--lp-stroke-default)}
.gs-step__mark{width:var(--lp-size-6);height:var(--lp-size-6);flex:none;box-sizing:border-box;
  border-radius:var(--lp-radius-full);border:1.5px solid var(--lp-text-tertiary);
  display:flex;align-items:center;justify-content:center}
/* The next step's empty ring is brighter than the ones behind it, so the eye lands on the row
   that carries the filled button without a second colour being spent. */
.gs-step__mark--next{border-color:var(--lp-text-primary)}
.gs-step__mark--done{border-color:var(--lp-success);background:var(--lp-success)}
.gs-step__mark--done svg{width:var(--lp-icon-sm);height:var(--lp-icon-sm);fill:none;stroke:var(--lp-text-on-accent);
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.gs-step__body{flex-grow:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.gs-step__title{font-size:var(--lp-text-md);font-weight:var(--lp-font-medium);color:var(--lp-text-primary)}
.gs-step--done .gs-step__title{color:var(--lp-text-tertiary);text-decoration:line-through;
  text-decoration-color:var(--lp-stroke-strong)}
.gs-step__hint{font-size:var(--lp-text-sm);line-height:var(--lp-leading-normal);color:var(--lp-text-tertiary)}
.gs-step__action{flex:none}
.gs-hide{color:var(--lp-text-secondary)}
.gs-hide:hover{color:var(--lp-text-primary)}
.gs-sheet__foot{margin-top:0;padding-top:var(--lp-space-16);border-top:var(--lp-border-thin) solid var(--lp-stroke-default)}

@media (max-width:767px){
  /* A 44px button beside two lines of text leaves the text about 150px on a 390 screen, so on a
     phone the button drops under the words it belongs to (board StartPhoneSheet). */
  .gs-step{align-items:flex-start}
  .gs-step__body{gap:var(--lp-space-4)}
  .gs-step__action{flex:none;width:100%;margin-top:10px}
  .gs-step{flex-wrap:wrap}
  .gs-step__action .btn{width:auto}
  /* Hide sits under Close, so the way out is the one the thumb reaches first. */
  .gs-sheet__foot{flex-direction:column-reverse;align-items:stretch}
  .gs-sheet__foot .btn{width:100%}
}

/* The line that says a step just ticked. A notification, not a celebration: one tick, one count,
   one way onward, and it clears itself. */
.gs-toast{position:fixed;left:var(--lp-space-16);right:var(--lp-space-16);bottom:104px;z-index:var(--lp-z-modal);
  display:flex;align-items:center;gap:var(--lp-space-12);box-sizing:border-box;
  padding:var(--lp-space-12) var(--lp-space-12) var(--lp-space-12) var(--lp-space-16);
  border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);
  background:var(--lp-bg-elevated);box-shadow:var(--lp-shadow-m)}
.gs-toast__mark{width:var(--lp-size-6);height:var(--lp-size-6);flex:none;border-radius:var(--lp-radius-full);
  background:var(--lp-success);display:flex;align-items:center;justify-content:center}
.gs-toast__mark svg{width:var(--lp-icon-sm);height:var(--lp-icon-sm);fill:none;stroke:var(--lp-text-on-accent);
  stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
.gs-toast__text{flex-grow:1;min-width:0;font-size:var(--lp-text-base);line-height:var(--lp-leading-snug);
  color:var(--lp-text-primary)}
.gs-toast__count{color:var(--lp-text-tertiary)}
.gs-toast__next{flex:none;padding-inline:var(--lp-space-12);min-height:var(--lp-height-lg);color:var(--lp-text-primary)}
@media (min-width:768px){
  /* On a desktop it sits over the content column rather than spanning the shell, so it never
     reaches across the sidebar. */
  .gs-toast{left:auto;right:var(--lp-space-24);bottom:var(--lp-space-24);width:420px}
}

/* ==========================================================================
   APPS PAGE v2 (canvas boards AppsDesktopSolid / AppsPhoneSolid, approved by Kenz 2026-09-22).
   Scoped to the page, the convention Collections v1 set, so the old .app-card geometry above stays
   the fallback for anything else that borrows the class. The filter row is gone: five apps arrive
   in named groups and the group heading carries the count.
   ========================================================================== */

.page[data-page="apps"] .apps-group{display:block;flex:none}
.page[data-page="apps"] .apps-group__label{margin:var(--lp-space-24) 0 var(--lp-space-12);
  font-size:var(--lp-text-sm);font-weight:var(--lp-font-semibold);letter-spacing:0.6px;
  text-transform:uppercase;color:var(--lp-text-tertiary)}

/* The lead card: a picture of the thing working, then the thing's name and the one filled button
   on the screen. Its body is a grid so the same five children re-place themselves per width
   instead of being written twice. */
/* `flex: none` is load-bearing, not tidiness. `.page-inner` is a column flex container, and
   `overflow: hidden` (which the banner needs, to be clipped by the card's corners) makes this a
   scroll container, whose automatic minimum size is zero. Without it the article was crushed from
   407px to 111px and only a strip of the banner showed, with the whole card body invisible and no
   error anywhere (measured in the demo at 1280, 2026-09-22). The groups below take it for the
   same reason. */
.page[data-page="apps"] .apps-hero{display:block;flex:none;margin-top:var(--lp-space-24);
  border-radius:var(--lp-radius-m);border:var(--lp-border-thin) solid var(--lp-stroke-default);
  background:var(--lp-bg-surface);overflow:hidden}
.page[data-page="apps"] .apps-hero__banner{display:block;width:100%;height:300px;object-fit:cover;
  object-position:center top;border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default)}
.page[data-page="apps"] .apps-hero__body{display:grid;align-items:center;
  grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-areas:"icon name action" "icon desc action" "icon meta action";
  column-gap:var(--lp-space-20);row-gap:var(--lp-space-4);padding:var(--lp-space-20) var(--lp-space-24)}
.page[data-page="apps"] .app-card__icon--hero{grid-area:icon}
.page[data-page="apps"] .apps-hero__name{grid-area:name;font-size:var(--lp-text-xl);
  font-weight:var(--lp-font-semibold);color:var(--lp-text-primary)}
.page[data-page="apps"] .apps-hero__desc{grid-area:desc;font-size:var(--lp-text-base);
  line-height:var(--lp-leading-normal);color:var(--lp-text-secondary)}
.page[data-page="apps"] .apps-hero__meta{grid-area:meta}
.page[data-page="apps"] .apps-hero__action{grid-area:action}

/* The icon is the app's own image, shown at the size the board draws. No colour is set here: the
   fill belongs to the uploaded artwork, so the page never has to guess an app's colour. */
.page[data-page="apps"] .app-card__icon{width:56px;height:56px;border-radius:15px;overflow:hidden;
  background:var(--lp-bg-elevated);flex-shrink:0}
.page[data-page="apps"] .app-card__icon img{width:100%;height:100%;object-fit:cover;display:block}
.page[data-page="apps"] .app-card__icon--hero{width:64px;height:64px;border-radius:17px}

/* Three to a row on a desktop, one under the next on a phone; a card is a column so its button
   sits on the same baseline whatever the description does. */
.page[data-page="apps"] .apps-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--lp-space-12)}
.page[data-page="apps"] .app-card{display:flex;flex-direction:column;align-items:stretch;gap:var(--lp-space-16);
  min-height:212px;box-sizing:border-box;padding:var(--lp-space-16)}
.page[data-page="apps"] .app-card__main{flex-grow:1;display:flex;flex-direction:column;gap:var(--lp-space-4)}
.page[data-page="apps"] .app-card__name{margin-bottom:0;font-size:var(--lp-text-md);font-weight:var(--lp-font-medium)}
/* The grid gives a description room for three lines, so it wraps instead of being cut at one. */
.page[data-page="apps"] .app-card__desc{margin-bottom:0;white-space:normal;overflow:visible;
  line-height:var(--lp-leading-normal)}
.page[data-page="apps"] .app-card__foot{display:flex;align-items:center;gap:var(--lp-space-12);flex-wrap:wrap}
.page[data-page="apps"] .app-card__meta{font-size:var(--lp-text-sm)}
.page[data-page="apps"] .apps-sentinel{height:1px}
.page[data-page="apps"] .apps-loading{display:flex;justify-content:center;padding:var(--lp-space-16) 0}
.page[data-page="apps"] .apps-error{margin-top:var(--lp-space-16)}

@media (max-width:767px){
  .page[data-page="apps"] .apps-grid{grid-template-columns:1fr}
  .page[data-page="apps"] .apps-hero__banner{height:200px}
  /* On a phone the sentence leaves the icon's side and takes the full width, so it is not read in
     a 230px gutter; the button then spans the card (board AppsPhoneSolid). */
  .page[data-page="apps"] .apps-hero__body{grid-template-columns:auto minmax(0,1fr);
    grid-template-areas:"icon name" "icon meta" "desc desc" "action action";
    align-items:center;column-gap:var(--lp-space-16);row-gap:var(--lp-space-4);padding:var(--lp-space-16)}
  .page[data-page="apps"] .apps-hero__desc{margin-top:var(--lp-space-8)}
  .page[data-page="apps"] .apps-hero__action{margin-top:var(--lp-space-16)}
  .page[data-page="apps"] .apps-hero__action .btn{width:100%}
  .page[data-page="apps"] .app-card__icon--hero{width:48px;height:48px;border-radius:12px}
  /* A 56px square beside two lines of text leaves the text 230px at 390, so the small cards become
     rows: icon at the left, name, sentence and button down the right. */
  .page[data-page="apps"] .app-card{display:grid;grid-template-columns:auto minmax(0,1fr);
    grid-template-areas:"icon main" ". foot";column-gap:var(--lp-space-16);row-gap:0;min-height:0;align-items:start}
  .page[data-page="apps"] .app-card__icon{grid-area:icon;width:48px;height:48px;border-radius:12px}
  .page[data-page="apps"] .app-card__main{grid-area:main}
  .page[data-page="apps"] .app-card__foot{grid-area:foot;margin-top:var(--lp-space-8)}
}

/* ==========================================================================
   ONE SPOTLIGHT (approved 2026-09-23, design system 10.x, canvas row "một Spotlight cho mọi bề mặt")
   The same component the extension draws. Three states: OPEN (input and four recent prompts),
   TYPING (Saved, History, then the row that turns the words into a prompt), "/" (the registry).
   A row is two lines, 52px, 56px on a phone. Row actions ride the hovered or focused row on a
   desktop; a phone shows one 44px "…" per row. Registry and copy: resources/js/shared/spotlight-commands.js.
   ========================================================================== */
.spotlight-backdrop{position:fixed;inset:0;background:var(--lp-overlay-dark);display:flex;align-items:flex-start;justify-content:center;padding-top:120px;z-index:var(--lp-z-spotlight);opacity:0;pointer-events:none;transition:opacity var(--lp-motion-mid) var(--lp-ease-out)}
.spotlight-backdrop--open{opacity:1;pointer-events:auto}
.spot{width:600px;max-width:calc(100vw - var(--lp-space-32));max-height:min(70vh,640px);background:var(--lp-bg-surface);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-l);box-shadow:var(--lp-shadow-l);display:flex;flex-direction:column;overflow:hidden;transform:translateY(12px);opacity:0;transition:transform var(--lp-motion-mid) var(--lp-ease-out),opacity var(--lp-motion-mid) var(--lp-ease-out)}
.spotlight-backdrop--open .spot{transform:none;opacity:1}
.spot__head{display:flex;align-items:center;gap:var(--lp-space-12);height:60px;padding:0 var(--lp-space-20);border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default);flex:none}
.spot__mark{width:var(--lp-size-5);height:var(--lp-size-5);display:block;flex:none;object-fit:contain}
.spot__input{flex:1;min-width:0;height:44px;border:0;background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-lg-plus);padding:0}
.spot__input:focus{outline:none;box-shadow:none}
.spot__input::placeholder{color:var(--lp-text-tertiary)}
.spot__mode{position:relative;flex:none}
.spot__modebtn{height:32px;padding:0 var(--lp-space-8);border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-tertiary);font:inherit;font-size:var(--lp-text-sm);white-space:nowrap;cursor:pointer}
.spot__modebtn:hover{color:var(--lp-text-primary);background:var(--lp-wash-hover)}
.spot__modebtn:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.spot__modelist{position:absolute;top:calc(100% + 6px);right:0;z-index:2;min-width:200px;padding:var(--lp-space-8);background:var(--lp-bg-surface);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);box-shadow:var(--lp-shadow-m);display:flex;flex-direction:column;gap:2px}
.spot__modeopt{display:flex;align-items:center;gap:var(--lp-space-8);min-height:36px;padding:0 var(--lp-space-12);border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-secondary);font:inherit;font-size:var(--lp-text-base);text-align:left;cursor:pointer}
.spot__modeopt:hover,.spot__modeopt[aria-selected="true"]{background:var(--lp-wash-hover);color:var(--lp-text-primary)}
.spot__modepill{width:8px;height:8px;border-radius:var(--lp-radius-full);flex:none}
.spot__pro{margin-left:auto;font-size:var(--lp-text-2xs);font-weight:var(--lp-font-semibold);letter-spacing:.04em;text-transform:uppercase;color:var(--lp-accent-text)}
.spot__cancel{display:none;height:44px;padding:0 0 0 var(--lp-space-4);border:0;background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base);font-weight:var(--lp-font-medium);flex:none;cursor:pointer}
.spot__sections{flex:1;min-height:0;overflow-y:auto;padding:var(--lp-space-4) var(--lp-space-8) var(--lp-space-8)}
.spot__label{padding:var(--lp-space-12) var(--lp-space-8) var(--lp-space-8);font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.spot__list{display:flex;flex-direction:column}
.spot__rule{height:1px;background:var(--lp-stroke-default);margin:var(--lp-space-8) var(--lp-space-8)}
.spot-row{position:relative;display:flex;align-items:center;gap:var(--lp-space-12);min-height:52px;padding:0 var(--lp-space-16);border-radius:var(--lp-radius-s);cursor:pointer;transition:background var(--lp-motion-mid) var(--lp-ease-out)}
.spot-row--active,.spot-row--menu{background:var(--lp-wash-hover);transition:background 0ms}
.spot-row--flash{background:var(--lp-overlay-accent-subtle)!important;transition:background 0ms!important}
.spot-row__icon{color:var(--lp-text-tertiary);display:inline-flex;flex:none}
.spot-row__icon svg{width:16px;height:16px}
.spot-row__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;padding:var(--lp-space-8) 0}
.spot-row__title{font-size:var(--lp-text-md);color:var(--lp-text-primary);line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:var(--lp-space-4)}
.spot-row__title--mono{font-family:var(--lp-font-mono);font-size:var(--lp-text-base)}
.spot-row__name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.spot-row__sub{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.spot-row__qa{display:none;align-items:center;gap:2px;flex:none}
.spot-row__btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-secondary);cursor:pointer;padding:0}
.spot-row__btn svg{width:15px;height:15px}
.spot-row__btn:hover{background:var(--lp-wash-strong);color:var(--lp-text-primary)}
.spot-row__btn--on{color:var(--lp-text-primary)}
.spot-row__more{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-secondary);cursor:pointer;padding:0;flex:none;margin-right:calc(var(--lp-space-8) * -1)}
.spot-row__more svg{width:16px;height:16px}
.spot-row__cta{display:none;font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);white-space:nowrap;flex:none}
.spot-menu{position:absolute;right:var(--lp-space-12);top:calc(100% - var(--lp-space-4));z-index:3;min-width:160px;padding:var(--lp-space-4);background:var(--lp-bg-surface);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);box-shadow:var(--lp-shadow-m);display:flex;flex-direction:column}
.spot-menu__item{min-height:44px;padding:0 var(--lp-space-12);border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base);text-align:left;cursor:pointer}
.spot-menu__item:hover{background:var(--lp-wash-hover)}
/* Status colours on TEXT use their -text tokens (27/09): the light fills measure under AA as text, e.g. Delete in the
   row menu at 4.43:1 on the light surface. Icons, borders and fills keep the fill tokens. */
.spot-menu__item--danger{color:var(--lp-error-text)}
.spot__foot{flex:none;display:flex;align-items:center;gap:var(--lp-space-16);padding:var(--lp-space-8) var(--lp-space-24) var(--lp-space-12);font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.spot__new{min-height:32px;padding:0;border:0;background:transparent;color:var(--lp-text-secondary);font:inherit;font-size:var(--lp-text-sm);cursor:pointer;position:relative}
.spot__new::before{content:"";position:absolute;inset:-6px -8px}
.spot__new:hover{color:var(--lp-text-primary)}
.spot__new:focus-visible{outline:none;box-shadow:var(--lp-focus-ring);border-radius:var(--lp-radius-xs)}
@media (hover:hover) and (pointer:fine){
  .spot-row__qa{display:inline-flex}
  .spot-row__qa .spot-row__btn{opacity:0;pointer-events:none;transition:opacity var(--lp-motion-fast)}
  .spot-row--active .spot-row__btn,.spot-row--menu .spot-row__btn,
  .spot-row__qa .spot-row__btn--on{opacity:1;pointer-events:auto}
  /* Every row keeps the room its actions and "Copy" need, so a name truncates at the same place on every row
     and does not re-truncate when the pointer moves onto it (Kenz, 2026-09-23). */
  .spot-row__cta{display:inline;visibility:hidden}
  .spot-row--active .spot-row__cta{visibility:visible}
  .spot-row__more{display:none}
}
@media (max-width:520px){
  .spotlight-backdrop{padding-top:12px}
  .spot{max-width:100%;max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px);border-radius:0;border-left:0;border-right:0}
  .spot__head{height:56px;padding:0 var(--lp-space-16) 0 var(--lp-space-20)}
  .spot__cancel{display:inline-flex;align-items:center}
  .spot__modebtn{height:44px;padding:0 var(--lp-space-8)}
  .spot__foot .spot__new{min-height:44px}
  .spot-row{min-height:56px}
  .spot__foot{padding-left:var(--lp-space-20)}
}
@media (prefers-reduced-motion:reduce){.spotlight-backdrop,.spot,.spot-row{transition:none}}

/* ==========================================================================
   COLLECTIONS CARD v2 (approved 2026-09-23, canvas "Đề xuất 23/09: Collections")
   A card is a Spotlight row plus two preview lines. Text only by default; the pin mark always sits
   beside the name; on a desktop Copy, Pin and "…" appear on the hovered or focused card; a phone
   shows Copy and "…" at 44px because it has no hover. Filter chips and the grid are unchanged.
   ========================================================================== */
.page[data-page="collections"] .card{gap:var(--lp-space-8);min-height:148px}
.page[data-page="collections"] .card__top{align-items:center;min-height:28px}
.page[data-page="collections"] .card__title{font-size:var(--lp-text-md);font-weight:var(--lp-font-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The pin mark belongs to the NAME, so it sits right after it on the name's line, the same glyph and place
   as a Spotlight row (2026-09-23; before, a nameless prompt left it floating alone on the card's first line). */
.page[data-page="collections"] .card__title{display:flex;align-items:center;gap:var(--lp-space-4)}
.page[data-page="collections"] .card__name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.page[data-page="collections"] .card__actions{opacity:1;margin:0 calc(var(--lp-space-8) * -1) 0 0;gap:0}
.page[data-page="collections"] .card__action-btn{width:44px;height:44px;border-radius:var(--lp-radius-s);color:var(--lp-text-secondary)}
.page[data-page="collections"] .card__action-btn svg{width:16px;height:16px}
.page[data-page="collections"] .card__action-btn--desk{display:none}
.page[data-page="collections"] .card__preview{font-size:var(--lp-text-base);line-height:1.5}
.page[data-page="collections"] .card__meta{gap:var(--lp-space-8);font-size:var(--lp-text-sm);flex-wrap:wrap}
.page[data-page="collections"] .card__example{display:inline-flex;align-items:center;gap:4px;margin-left:var(--lp-space-4);color:var(--lp-text-secondary)}
.page[data-page="collections"] .card__example svg{width:12px;height:12px}
@media (hover:hover) and (pointer:fine){
  .page[data-page="collections"] .card__actions{opacity:1;margin-right:calc(var(--lp-space-4) * -1)}
  .page[data-page="collections"] .card__action-btn{opacity:0;transition:opacity var(--lp-motion-mid) var(--lp-ease-out)}
  .page[data-page="collections"] .card:hover .card__action-btn,.page[data-page="collections"] .card:focus-within .card__action-btn,
  .page[data-page="collections"] .card__action-btn--pin.is-on{opacity:1;transition:opacity var(--lp-motion-instant)}
  .page[data-page="collections"] .card:hover,.page[data-page="collections"] .card:focus-within{border-color:var(--lp-text-tertiary)}
  .page[data-page="collections"] .card__action-btn{width:28px;height:28px}
  .page[data-page="collections"] .card__action-btn--desk{display:inline-flex}
}

/* ==========================================================================
   PROMPT EDITOR, progressive disclosure (approved 2026-09-23, design system 10.x "editor focal")
   The name and the body are the surface. Collection, tag and Example result are one row of pills
   that open in place: a pill holding a value has a solid border, an empty one is dashed. Copy is
   a text button in the foot, Save the only accent, the × the one closer, Expand desktop only.
   ========================================================================== */
.pe__head{display:flex;align-items:center;gap:var(--lp-space-8)}
.pe__kind{flex:1;font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.pe__iconbtn{display:inline-flex;flex:none;align-items:center;justify-content:center;width:44px;height:44px;border:0;border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-secondary);cursor:pointer;padding:0;margin-right:calc(var(--lp-space-8) * -1)}
.pe__iconbtn + .pe__iconbtn{margin-left:calc(var(--lp-space-4) * -1)}
.pe__iconbtn svg{width:16px;height:16px}
.pe__iconbtn:hover{background:var(--lp-wash-hover);color:var(--lp-text-primary)}
.pe__iconbtn:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.pe__expand{display:none}
.pe{display:flex;flex-direction:column;gap:var(--lp-space-16);padding-bottom:var(--lp-space-8)}
.pe__title{width:100%;border:0;border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:0;background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-xl);font-weight:var(--lp-font-semibold);line-height:1.35;padding:var(--lp-space-4) 0 var(--lp-space-8)}
.pe__title::placeholder{color:var(--lp-text-tertiary);font-weight:var(--lp-font-medium)}
.pe__title:focus{outline:none;border-bottom-color:var(--lp-text-tertiary);box-shadow:none}
.pe__body{width:100%;min-height:150px;border:0;border-radius:0;background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-md);line-height:1.7;padding:0;resize:vertical}
.pe__body::placeholder{color:var(--lp-text-tertiary)}
.pe__body:focus{outline:none;box-shadow:none}
.lp-sheet--xl .pe__body{min-height:min(52vh,520px)}
.pe__pills{display:flex;flex-wrap:wrap;gap:var(--lp-space-8)}
.pe__pill{display:inline-flex;align-items:center;gap:var(--lp-space-8);min-height:32px;padding:0 var(--lp-space-12);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base);cursor:pointer;position:relative;max-width:100%}
.pe__pill::before{content:"";position:absolute;inset:-6px 0}
.pe__pill svg{width:13px;height:13px;flex:none}
.pe__pill--empty{border-style:dashed;color:var(--lp-text-secondary)}
.pe__pill--open{background:var(--lp-wash-hover);border-color:var(--lp-text-tertiary)}
.pe__pill:hover{background:var(--lp-wash-hover)}
.pe__pill:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.pe__dot{width:8px;height:8px;border-radius:var(--lp-radius-full);flex:none;display:inline-block}
.pe__panel{display:flex;flex-direction:column;gap:var(--lp-space-8);padding:var(--lp-space-12);border-radius:var(--lp-radius-m);background:var(--lp-bg-elevated)}
.pe__panel-label{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary)}
.pe__chips{display:flex;flex-wrap:wrap;gap:var(--lp-space-8);align-items:center}
.pe__chip{display:inline-flex;align-items:center;gap:var(--lp-space-8);min-height:32px;padding:0 var(--lp-space-12);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-secondary);font:inherit;font-size:var(--lp-text-base);cursor:pointer;position:relative}
.pe__chip::before{content:"";position:absolute;inset:-6px 0}
.pe__chip--on{background:var(--lp-text-primary);border-color:var(--lp-text-primary);color:var(--lp-bg-base)}
.pe__chip:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.pe__new{min-height:32px;width:160px;max-width:100%;padding:0 var(--lp-space-12);border:var(--lp-border-thin) dashed var(--lp-stroke-default);border-radius:var(--lp-radius-full);background:transparent;color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base)}
.pe__new:focus{outline:none;border-style:solid;border-color:var(--lp-text-tertiary);box-shadow:none}
.pe__colors{display:flex;gap:var(--lp-space-8);align-items:center}
.pe__color{width:24px;height:24px;border:2px solid transparent;border-radius:var(--lp-radius-full);cursor:pointer;padding:0;position:relative}
.pe__color::before{content:"";position:absolute;inset:-10px}
.pe__color--on{border-color:var(--lp-text-primary);box-shadow:0 0 0 2px var(--lp-bg-elevated) inset}
.pe__color:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.pe__example{width:100%;min-height:72px;border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-s);background:var(--lp-bg-input);color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-base);line-height:1.6;padding:var(--lp-space-8) var(--lp-space-12);resize:vertical}
.pe__example:focus{outline:none;border-color:var(--lp-text-tertiary);box-shadow:none}
.pe__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--lp-space-8)}
.pe__link{display:flex;align-items:center;gap:var(--lp-space-8);min-height:44px;padding:var(--lp-space-8) var(--lp-space-12);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);color:var(--lp-text-primary);text-decoration:none}
.pe__link:hover{border-color:var(--lp-text-tertiary)}
.pe__link svg{width:12px;height:12px;color:var(--lp-text-tertiary);flex:none}
.pe__link-text{display:flex;flex-direction:column;min-width:0;flex:1}
.pe__link-host{font-size:var(--lp-text-base)}
.pe__link-url{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pe__link-open{font-size:var(--lp-text-base);font-weight:var(--lp-font-medium);flex:none}
.pe__foot{display:flex;align-items:center;gap:var(--lp-space-8);padding-top:var(--lp-space-16);border-top:var(--lp-border-thin) solid var(--lp-stroke-default)}
.pe__foot .btn{min-width:0;min-height:44px}
.pe__copy{display:inline-flex;align-items:center;gap:var(--lp-space-8);margin-right:auto;color:var(--lp-text-secondary)}
.pe__copy svg{width:14px;height:14px}
@media (min-width:768px){
  .pe__expand{display:inline-flex}
  .pe__iconbtn{width:32px;height:32px;margin-right:0}
  .pe__foot .btn{min-height:32px;font-size:var(--lp-text-base)}
}

/* Phone tap floor for the Collections row (canvas CollPhone and CollEditPhone, raised to 44 on 2026-09-23 after
   app#134 shipped them at 32 and 36): the filter strip and the editor's pill row. */
@media (max-width:767px){
  .page[data-page="collections"] .filter-chip{min-height:44px}
  .pe__pill{min-height:44px}
  .pe__pill::before{inset:0}
}
/* The narrowest phones still in use (320): the brand mark gives its room to the input so the placeholder
   reads whole beside the mode control and Cancel. */
@media (max-width:360px){
  .spot__mark{display:none}
  .spot__head{gap:var(--lp-space-8);padding:0 var(--lp-space-12) 0 var(--lp-space-16)}
  .spot__input{font-size:var(--lp-text-lg)}
  .spot__modebtn{padding:0 var(--lp-space-4)}
}

/* Session composer on small phones (measured 2026-09-23 on the demo: the field's text box was 104px at
   360 and 64px at 320 for a 111px placeholder, so "Task or idea..." broke onto a hidden second line).
   360 is the commonest Android width. Up to 400: tighter shell, bar and field insets. Up to 340: the mode
   button drops its colour dot and keeps the word, because the word is what names the mode (production sets
   both modes' dot to #ffffff, so the dot alone says nothing and vanishes on the light theme). */
@media (max-width:400px){
  .ns-input-bar-shell{padding-left:var(--lp-space-12);padding-right:var(--lp-space-12)}
  .ns-input-bar{padding-left:var(--lp-space-8);padding-right:var(--lp-space-8);gap:var(--lp-space-8)}
  .ns-input-field{padding-left:var(--lp-space-8)}
  .ns-mode-addon{padding:0 var(--lp-space-8)}
}
@media (max-width:340px){
  .ns-mode-pill{display:none}
  .ns-mode-addon{gap:var(--lp-space-4);padding:0 var(--lp-space-4)}
}

/* PINNED IS THE PIN BUTTON (2026-09-23, Kenz: the on and off pins were hard to tell apart, and the mark after
   the name floated). On: the glyph filled, primary text colour, and the button stays visible at rest in the
   same place on every card and row. Off: the outline in the resting grey, shown only where actions show.
   On a phone, where Pin otherwise lives in the "…" menu, an on pin shows as its own 44px button. */
.page[data-page="collections"] .card__action-btn--pin.is-on,.spot-row__btn--on{color:var(--lp-text-primary)}
.page[data-page="collections"] .card__action-btn--pin.is-on svg path,.spot-row__btn--on svg path{fill:currentColor}
.page[data-page="collections"] .card__action-btn--pin.is-on{display:inline-flex;align-items:center;justify-content:center}
@media not all and (hover:hover) and (pointer:fine){
  .spot-row:has(.spot-row__btn--on) .spot-row__qa{display:inline-flex}
  .spot-row__qa .spot-row__btn:not(.spot-row__btn--on){display:none}
  .spot-row__qa .spot-row__btn--on{width:44px;height:44px}
}
.lp-sheet--placing{transition:none!important}
/* THE row menu (RowMenu.vue): one menu for every "…" on a row, the popover look, fixed in the viewport. */
.row-menu{width:200px;max-height:none;padding:var(--lp-space-4);transform:none;z-index:1100;display:flex;flex-direction:column;gap:2px}
.row-menu .popover__item{height:auto;min-height:36px}
.row-menu .row-menu__item--danger{color:var(--lp-error-text)}
@media not all and (hover:hover) and (pointer:fine){ .row-menu .popover__item{min-height:44px} }
/* Settings keeps one height whichever tab is open (Kenz, 2026-09-23: Profile 452px, Team 385px, Preferences
   640px made the dialog jump on every tab). The body scrolls inside it. */
/* Settings > Preferences > Behaviour (2026-09-23): the switch rows use the options-list row, full width. */
.pref-switch{width:100%;padding:0;background:transparent;border:0;text-align:left}
.pref-kbd{font:inherit;font-size:var(--lp-text-sm);padding:2px var(--lp-space-8);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-s);color:var(--lp-text-secondary)}
/* Settings > Profile > Delete account (2026-09-23) */
/* Manage tags: the colour dot is the colour control (2026-09-23) */
.tags-dot-btn{display:inline-flex;align-items:center;justify-content:center;background:transparent;border:0;padding:0;width:32px;height:32px;border-radius:var(--lp-radius-full)}
@media (max-width:767px){ .tags-dot-btn{width:44px;height:44px} }

/* ========================================
   LAYOUT GRAMMAR L1 (approved by Kenz 2026-09-23, design system 10.x, canvas row "một ngữ pháp bố cục")
   One anatomy for every settings-like surface, every value from the 4-grid. Proven first on Settings.
   ROW    min 56 (64 on a phone), 12 by 16 inside; label 14 over hint 12, 2 apart; the control on
          the right, never wrapping. A row that opens something shows its value and a chevron.
   GROUP  one continuous frame (radius 12) holding its rows, a 1px divider between them; the label 12,
          8 above the frame and 16 in from its edge; groups 32 apart.
   ENUM   ONE segmented control. Selected is a raised surface, never the accent. On a phone it moves under
          its label, full width, a 40 tall option inside a 44 target.
   SHEET  desktop, a 200 rail beside a column of at most 520; phone, a list of sections, then one page each.
   ======================================== */
.lp-sheet--settings{--lp-sheet-pad:0;background:var(--lp-bg-base);height:88vh;height:88dvh}
@media (min-width:768px){.lp-sheet--settings{--lp-sheet-w:840px;height:min(640px,80vh)}}
.lp-sheet.lp-sheet--settings .lp-sheet__head{padding:0;border-bottom:var(--lp-border-thin) solid var(--lp-stroke-default)}
.lp-sheet.lp-sheet--settings:has(.lp-set) > .lp-sheet__scroll{padding:0;overflow:hidden;display:flex;flex-direction:column}
.lp-set-head{display:flex;align-items:center;gap:var(--lp-space-8);min-height:56px;padding:0 var(--lp-space-16) 0 var(--lp-space-32)}
.lp-set-head .lp-sheet__title{margin:0;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lp-set-head .pe__iconbtn{margin-right:0}
.lp-set-head__back,.lp-set-head__title--page{display:none}
.lp-set{flex:1;min-height:0;display:flex}
.lp-set__main{flex:1;min-width:0;overflow-y:auto;overscroll-behavior:contain;padding:var(--lp-space-32)}
.lp-set__col{max-width:520px}
.lp-set__section{display:flex;flex-direction:column;gap:var(--lp-space-32)}
.lp-set__section[hidden]{display:none}
.lp-set__rail{width:200px;flex:none;display:flex;flex-direction:column;justify-content:space-between;gap:var(--lp-space-16);padding:var(--lp-space-32) 0 var(--lp-space-24) var(--lp-space-32);overflow-y:auto}
.lp-set__tabs{display:flex;flex-direction:column;gap:var(--lp-space-4)}
.lp-set__tab{display:flex;align-items:center;min-height:36px;padding:0 var(--lp-space-12);border:0;border-radius:var(--lp-radius-s);background:transparent;color:var(--lp-text-secondary);font:inherit;font-size:var(--lp-text-base);text-align:left;cursor:pointer}
.lp-set__tab:hover{background:var(--lp-wash-hover);color:var(--lp-text-primary)}
.lp-set__tab:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.lp-set__tab--on,.lp-set__tab--on:hover{background:var(--lp-bg-surface);color:var(--lp-text-primary);font-weight:var(--lp-font-medium)}
.lp-set__legal{padding:0 var(--lp-space-12);row-gap:var(--lp-space-4)}
.lp-set__list{display:none}
@media (max-width:767px){
  .lp-set-head{padding:0 var(--lp-space-8) 0 var(--lp-space-16)}
  .lp-set-head:not(.lp-set-head--list){padding-left:var(--lp-space-4)}
  .lp-set-head:not(.lp-set-head--list) .lp-set-head__back{display:inline-flex}
  .lp-set-head:not(.lp-set-head--list) .lp-set-head__title--root{display:none}
  .lp-set-head:not(.lp-set-head--list) .lp-set-head__title--page{display:block}
  .lp-set__rail{display:none}
  .lp-set__main,.lp-set__list{padding:var(--lp-space-8) var(--lp-space-16) calc(var(--lp-space-24) + env(safe-area-inset-bottom))}
  .lp-set--list .lp-set__main{display:none}
  .lp-set--list .lp-set__list{display:flex;flex-direction:column;gap:var(--lp-space-24);flex:1;min-width:0;overflow-y:auto;overscroll-behavior:contain}
  .lp-set__legal{padding:0 var(--lp-space-16)}
}

.lp-group{display:flex;flex-direction:column}
.billing-panel{display:flex;flex-direction:column;gap:var(--lp-space-32)}
.lp-group__label{margin:0;padding:0 var(--lp-space-16) var(--lp-space-8);font-size:var(--lp-text-sm);font-weight:var(--lp-font-normal);line-height:1.5;color:var(--lp-text-tertiary)}
.lp-group__frame{border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);background:var(--lp-bg-surface);overflow:hidden}
.lp-group__frame > :not(:first-child){border-top:var(--lp-border-thin) solid var(--lp-stroke-default)}
.lp-group__note{margin:0;padding:var(--lp-space-8) var(--lp-space-16) 0;font-size:var(--lp-text-sm);line-height:1.5;color:var(--lp-text-tertiary)}
.lp-group__note.field-error,.lp-group__note.text-danger{color:var(--lp-error-text)}

.lp-row{display:flex;align-items:center;gap:var(--lp-space-16);box-sizing:border-box;width:100%;min-height:56px;padding:var(--lp-space-12) var(--lp-space-16);margin:0;border:0;border-radius:0;background:transparent;color:var(--lp-text-primary);font:inherit;text-align:left}
button.lp-row{cursor:pointer}
a.lp-row{text-decoration:none}
button.lp-row:hover,a.lp-row:hover{background:var(--lp-wash-hover)}
button.lp-row:active,a.lp-row:active{background:var(--lp-wash-active)}
button.lp-row:focus-visible,a.lp-row:focus-visible{outline:none;box-shadow:var(--lp-row-focus-ring)}
button.lp-row:disabled{cursor:not-allowed;opacity:var(--lp-opacity-disabled)}
.lp-row__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:calc(var(--lp-space-4) / 2)}
.lp-row__label{font-size:var(--lp-text-md);line-height:1.4;color:var(--lp-text-primary)}
.lp-row__hint{font-size:var(--lp-text-sm);line-height:1.5;color:var(--lp-text-tertiary)}
.lp-row__value,.lp-row__control{flex:none;display:flex;align-items:center;gap:var(--lp-space-8);white-space:nowrap;font-size:var(--lp-text-base);color:var(--lp-text-secondary)}
.lp-row__value--fit{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;display:block}
.lp-row__chev{font-size:var(--lp-text-lg);line-height:1;color:var(--lp-text-tertiary)}
.lp-row--danger .lp-row__label{color:var(--lp-error-text)}
.lp-row--stack{flex-direction:column;align-items:stretch;gap:var(--lp-space-12)}
.lp-row__inline{display:flex;gap:var(--lp-space-8)}
.lp-row__inline .input{flex:1;min-width:0}
.lp-row__panel{display:flex;flex-direction:column;gap:var(--lp-space-8);padding:var(--lp-space-4) var(--lp-space-16) var(--lp-space-16);border-top:0!important}
.lp-row__panel .input--password .input{width:100%}
.lp-row__actions{display:flex;justify-content:flex-end;gap:var(--lp-space-8);margin-top:var(--lp-space-8)}
.lp-row .pref-kbd{flex:none}
.lp-row .lp-switch{flex:none}

.lp-seg{--lp-seg-inset:2px;flex:none;display:inline-flex;border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:calc(var(--lp-radius-s) + var(--lp-seg-inset));background:var(--lp-bg-base)}
.lp-seg__opt{position:relative;isolation:isolate;min-width:44px;height:32px;padding:0 var(--lp-space-12);border:0;background:transparent;color:var(--lp-text-secondary);font:inherit;font-size:var(--lp-text-base);white-space:nowrap;cursor:pointer}
.lp-seg__opt::before{content:"";position:absolute;inset:var(--lp-seg-inset);z-index:-1;border-radius:var(--lp-radius-s);background:transparent}
.lp-seg__opt:hover{color:var(--lp-text-primary)}
.lp-seg__opt:hover::before{background:var(--lp-wash-hover)}
.lp-seg__opt[aria-pressed="true"]{color:var(--lp-text-primary);font-weight:var(--lp-font-medium)}
.lp-seg__opt[aria-pressed="true"]::before{background:var(--lp-bg-elevated);box-shadow:var(--lp-shadow-s)}
.lp-seg__opt:focus-visible{outline:none}
.lp-seg__opt:focus-visible::before{box-shadow:var(--lp-focus-ring)}
@media (max-width:767px){
  .lp-row{min-height:64px}
  .lp-row--enum{flex-direction:column;align-items:stretch;gap:var(--lp-space-12)}
  .lp-row--enum .lp-seg{display:flex;width:100%}
  /* Every segmented control is a 44 target on a phone, not only the one in a settings row: Earn's customers-per-month
     control measured 44x32 at 320 (demo/grammar-walk.mjs). The raised option stays 40 inside it (the 2px inset). */
  .lp-seg__opt{height:44px}
  .lp-row--enum .lp-seg__opt{flex:1}
  .lp-row__actions .btn{flex:1}
}
/* A card never grows past its column (2026-09-23, Kenz: "thẻ prompt ở mobile bị mất góc phải"). A long name is
   nowrap with an ellipsis, and a grid item's automatic minimum is its min-content, so one long name widened the
   column to 776px inside a 358px phone page and the page's overflow:hidden cut the card's right side off. */
.collections-grid > *{min-width:0}
/* The chip strip scrolls sideways only (2026-09-23): overflow-x auto made y auto too, so the strip was a
   two-way scroller; a sideways strip never scrolls up and down. */
.filter-tabs{overflow-y:hidden}
/* Blanks in a saved prompt (P10, 2026-09-24; canvas row "Đề xuất 24/09", board VarFill). Choosing a prompt
   that holds {{name}} opens this step inside the Spotlight: the prompt as it will be copied, one field per
   blank (two columns on a desktop, one on a phone), Back and Copy. Holes are marked by an underline and a
   tint, never by a text colour of their own, so every word keeps the surface's own contrast. */
.spot__filltitle{flex:1;min-width:0;font-size:var(--lp-text-lg-plus);color:var(--lp-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.spot-fill{display:flex;flex-direction:column;gap:var(--lp-space-16);padding:var(--lp-space-12) var(--lp-space-16) var(--lp-space-4)}
.spot-fill__preview{margin:0;max-height:9.6em;overflow-y:auto;font-size:var(--lp-text-base);line-height:var(--lp-leading-relaxed);color:var(--lp-text-secondary);white-space:pre-wrap;overflow-wrap:anywhere}
.spot-fill__hole{color:var(--lp-text-primary);border-bottom:var(--lp-border-thin) dashed var(--lp-stroke-strong);background:color-mix(in srgb,var(--lp-accent-base) 10%,transparent);border-radius:var(--lp-radius-xs) var(--lp-radius-xs) 0 0;padding:0 2px}
.spot-fill__hole--typed{border-bottom-style:solid;border-bottom-color:var(--lp-accent-base)}
.spot-fill__hole--empty{color:var(--lp-text-secondary)}
.spot-fill__fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--lp-space-12)}
.spot-fill__field{display:flex;flex-direction:column;gap:var(--lp-space-4);min-width:0}
.spot-fill__name{font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.spot-fill__input{height:40px;box-sizing:border-box;padding:0 var(--lp-space-12);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);background:var(--lp-bg-input);color:var(--lp-text-primary);font:inherit;font-size:var(--lp-text-md);min-width:0}
.spot-fill__input::placeholder{color:var(--lp-text-tertiary)}
.spot-fill__input:focus{outline:none;border-color:var(--lp-accent-base)}
.spot__foot--fill{gap:var(--lp-space-12)}
.spot__foot--fill .spot__hint{flex:1;min-width:0}
.spot__foot--fill .spot__back{padding:0 var(--lp-space-4)}
.pe__blanks{margin:0;font-size:var(--lp-text-sm);color:var(--lp-text-tertiary);overflow-wrap:anywhere}
.pe__blanks-names{color:var(--lp-text-secondary)}
@media (max-width:520px){
  .spot-fill__fields{grid-template-columns:minmax(0,1fr)}
  .spot-fill__input{height:44px}
  .spot__foot--fill .spot__hint{visibility:hidden}
  .spot__foot--fill .btn{height:44px}
}

/* ==========================================================================
   APPS PAGE: YOUR APPS AND THE ONE LEAD CARD (2026-09-24; canvas boards WaveMyApps D3 and WaveStates D9,
   design system 10.x closed 2026-09-23). A tile is the board's: 16 inside, 12 corners, a 44 icon beside the
   name (14/500) and the usage line (12). The icon is the site's own favicon on a neutral square, the first
   letter when the favicon does not load. The "…" follows the row-action rule: on a desktop it shows on the
   hovered or focused tile, on a phone it is always there at 44.
   ========================================================================== */
.page[data-page="apps"] .apps-mine__grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--lp-space-12)}
.page[data-page="apps"] .apps-mine__empty,
.apps-mine__empty{margin:0 0 var(--lp-space-12);font-size:var(--lp-text-base);line-height:1.5;color:var(--lp-text-secondary)}
.page[data-page="apps"] .my-app{position:relative;display:flex;align-items:center;gap:var(--lp-space-8);min-width:0;box-sizing:border-box;
  padding:var(--lp-space-16);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-m);
  background:var(--lp-bg-surface);color:var(--lp-text-primary);font:inherit;text-align:left}
.page[data-page="apps"] .my-app__open{flex:1;min-width:0;display:flex;align-items:center;gap:var(--lp-space-12);color:inherit;text-decoration:none;border-radius:var(--lp-radius-s,8px)}
.page[data-page="apps"] .my-app__open:focus-visible,
.page[data-page="apps"] .my-app__more:focus-visible,
.page[data-page="apps"] .my-app--add:focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
.page[data-page="apps"] .my-app:hover{border-color:var(--lp-stroke-light)}
.my-app__icon{width:44px;height:44px;flex:none;box-sizing:border-box;border-radius:12px;background:var(--lp-bg-elevated);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.my-app__icon img{width:24px;height:24px;object-fit:contain;display:block}
.my-app__icon--sm{width:32px;height:32px;border-radius:8px}
.my-app__icon--sm img{width:20px;height:20px}
.my-app__letter{font-size:var(--lp-text-lg);font-weight:var(--lp-font-semibold);color:var(--lp-text-primary)}
.my-app__icon--add{background:transparent;border:var(--lp-border-thin) dashed var(--lp-stroke-default);color:var(--lp-text-secondary)}
.my-app__icon--add svg,.page[data-page="apps"] .my-app__more svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round}
.page[data-page="apps"] .my-app__more svg{fill:currentColor;stroke:none}
.page[data-page="apps"] .my-app__text{min-width:0;display:flex;flex-direction:column;gap:2px}
.page[data-page="apps"] .my-app__name{font-size:var(--lp-text-md);font-weight:var(--lp-font-medium);line-height:1.4;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.page[data-page="apps"] .my-app__usage{font-size:var(--lp-text-sm);line-height:1.5;color:var(--lp-text-tertiary)}
.page[data-page="apps"] .my-app__more{flex:none;width:32px;height:32px;padding:0;border:0;border-radius:var(--lp-radius-full);
  background:transparent;color:var(--lp-text-secondary);display:flex;align-items:center;justify-content:center;cursor:pointer;opacity:0}
.page[data-page="apps"] .my-app:hover .my-app__more,
.page[data-page="apps"] .my-app:focus-within .my-app__more,
.page[data-page="apps"] .my-app__more[aria-expanded="true"]{opacity:1}
.page[data-page="apps"] .my-app__more:hover{background:var(--lp-wash-hover);color:var(--lp-text-primary)}
.page[data-page="apps"] .my-app--add{cursor:pointer;border-style:dashed;background:transparent;gap:var(--lp-space-12);color:var(--lp-text-secondary)}
.page[data-page="apps"] .my-app--add:hover{color:var(--lp-text-primary)}
/* The lead card's two buttons: Not now then the one filled button, together on the right (Phụ then Chính). */
.page[data-page="apps"] .apps-hero__action{display:flex;align-items:center;gap:var(--lp-space-8);justify-content:flex-end}
.apps-pick .my-app__icon,.apps-pick .my-app__letter{flex:none}
.apps-prompt__name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
@media (max-width:767px){
  .page[data-page="apps"] .apps-mine__grid{grid-template-columns:minmax(0,1fr)}
  .page[data-page="apps"] .my-app{padding:var(--lp-space-12) var(--lp-space-8) var(--lp-space-12) var(--lp-space-16);min-height:64px}
  .page[data-page="apps"] .my-app--add{padding-right:var(--lp-space-16)}
  .page[data-page="apps"] .my-app__more{width:44px;height:44px;opacity:1}
  .page[data-page="apps"] .apps-hero__action .btn{width:auto;min-height:44px}
  .page[data-page="apps"] .apps-hero__action .btn--primary{flex:1}
}
@media (hover:none){ .page[data-page="apps"] .my-app__more{opacity:1} }
/* "Did it work?" (D6, 2026-09-24): a quiet bar under the top bar, never over the composer (measured: at the bottom it covered it). */
.diw{position:fixed;left:50%;transform:translateX(-50%);top:calc(env(safe-area-inset-top,0px) + 68px);width:max-content;z-index:90;display:flex;align-items:center;gap:var(--lp-space-12);flex-wrap:wrap;max-width:min(560px,calc(100vw - 24px));padding:var(--lp-space-8) var(--lp-space-8) var(--lp-space-8) var(--lp-space-16);background:var(--lp-bg-elevated,var(--lp-bg-surface));border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-l);box-shadow:var(--lp-shadow-m,0 8px 24px rgba(0,0,0,.18));color:var(--lp-text-primary);font-size:var(--lp-text-md)}
.diw__q{flex:1 1 220px;min-width:0}
.diw__q b{font-weight:var(--lp-font-semibold)}
.diw__acts{display:inline-flex;gap:var(--lp-space-8)}
/* the × is THE close control (.pe__iconbtn, 44 target); this only places it */
@media (max-width:767px){ .diw{left:12px;right:12px;transform:none;width:auto;max-width:none} .diw .btn--sm{min-height:44px;min-width:44px} }
.diw{padding-right:48px}
.diw__close{position:absolute;top:50%;right:6px;transform:translateY(-50%)}
@media (max-width:767px){ .diw__close{top:6px;transform:none} .diw__acts{width:100%} }
/* Shared page (D7, 2026-09-24) */
.share-page .page-inner{max-width:720px;margin:0 auto;width:100%}
.share-page__by{margin:0 0 var(--lp-space-4);font-size:var(--lp-text-sm);color:var(--lp-text-secondary)}
.share-card{position:relative;border:var(--lp-border-thin) solid var(--lp-stroke-default);border-radius:var(--lp-radius-l);background:var(--lp-bg-surface);padding:var(--lp-space-16);margin:0 0 var(--lp-space-12)}
.share-card__name{font-size:var(--lp-text-md);font-weight:var(--lp-font-semibold);margin:0 0 var(--lp-space-8)}
.share-card__body{white-space:pre-wrap;margin:0 0 var(--lp-space-12);color:var(--lp-text-primary);line-height:1.55;overflow-wrap:anywhere}
.share-card__example{border-top:var(--lp-border-thin) solid var(--lp-stroke-default);padding-top:var(--lp-space-12);margin-bottom:var(--lp-space-12)}
.share-card__label{font-size:var(--lp-text-sm);color:var(--lp-text-secondary);margin-bottom:var(--lp-space-4)}
.share-card__example-text{white-space:pre-wrap;margin:0;overflow-wrap:anywhere}
.share-card__link{display:inline-flex;align-items:center;margin-top:var(--lp-space-4);margin-right:var(--lp-space-12);color:var(--lp-text-primary);text-decoration:underline;text-underline-offset:3px}
.share-page__foot{position:sticky;bottom:0;display:flex;flex-direction:column;gap:var(--lp-space-8);padding:var(--lp-space-12) 0 calc(env(safe-area-inset-bottom,0px) + var(--lp-space-12));background:var(--lp-bg-canvas,var(--lp-bg-base))}
.share-page__foot .btn--primary{min-height:44px}
.share-page__note{margin:0;text-align:center;color:var(--lp-text-secondary)}
.share-page__gone{padding:var(--lp-space-32) 0;display:flex;flex-direction:column;gap:var(--lp-space-12);align-items:flex-start}
/* A link row is a tap target on a phone too: .share-card__link measured 139x19 at 390 (demo/grammar-walk.mjs). */
@media (max-width:767px){ .share-card__copy, .share-card__link{min-height:44px} }
/* THE sheet close (LpSheet close-button, 2026-09-24): top right, same size and place as the editor's and Settings'. */
.lp-sheet__x{position:absolute;top:var(--lp-space-32);right:var(--lp-space-12);margin:0;z-index:2}
@media (min-width:768px){ .lp-sheet__x{top:var(--lp-space-20);right:var(--lp-space-20)} }
.lp-sheet:has(> .lp-sheet__x) .lp-sheet__title{padding-right:calc(var(--lp-space-32) + var(--lp-space-16))}
/* THE focus ring, for every control that has no rule of its own (2026-09-24). Focus styles were written per
   component, so each new control (segmented presets, option rows, sheet icons) shipped without one; a keyboard
   user could not see where they were. :where() keeps this at zero specificity: a component's own rule still wins. */
:where(button, a[href], [role="button"], [role="menuitem"], [role="switch"], [role="tab"], summary, [tabindex]:not([tabindex="-1"])):focus-visible{outline:none;box-shadow:var(--lp-focus-ring)}
/* States (2026-09-24): THE empty state (EmptyState.vue) and THE inline empty line. */
.lp-empty{display:flex;flex-direction:column;align-items:center;gap:var(--lp-space-8);padding:var(--lp-space-32) var(--lp-space-16);text-align:center;grid-column:1 / -1}
.lp-empty__title{margin:0;font-size:var(--lp-text-md);font-weight:var(--lp-font-semibold);color:var(--lp-text-primary)}
.lp-empty__text{margin:0;max-width:44ch;font-size:var(--lp-text-base);line-height:1.5;color:var(--lp-text-secondary)}
.lp-empty__action{margin-top:var(--lp-space-8)}
.lp-empty-line{margin:0;padding:var(--lp-space-24) var(--lp-space-16);text-align:center;font-size:var(--lp-text-base);color:var(--lp-text-tertiary)}
/* THE content loading state (SkeletonLines.vue) */
.lp-skeleton{display:flex;flex-direction:column;gap:var(--lp-space-8);padding:var(--lp-space-16) 0}
/* THE in-page message (InlineAlert.vue) */
.lp-alert{display:flex;align-items:center;gap:var(--lp-space-12);flex-wrap:wrap;padding:var(--lp-space-12) var(--lp-space-16);border-radius:var(--lp-radius-m);border:var(--lp-border-thin) solid var(--lp-stroke-default);border-left-width:var(--lp-space-4);background:var(--lp-bg-surface);color:var(--lp-text-primary);font-size:var(--lp-text-base);line-height:1.5;margin:var(--lp-space-12) 0}
.lp-alert__text{flex:1 1 auto;min-width:0}
.lp-alert--error{border-left-color:var(--lp-error)}
.lp-alert--warning{border-left-color:var(--lp-warning)}
.lp-alert--info{border-left-color:var(--lp-stroke-strong)}
