From ef29bb6eb3dfc7d5274c2e3fa4fc5ba30c732c78 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:22:49 -0500 Subject: [PATCH] update --- dist/asset-manifest.json | 7 + dist/components/dm-settings-modal.html | 108 + .../subscription-history-modal.html | 111 + dist/css/docs.fe4863d7877544b1.css | 77 + .../tailwind.generated.31c8693d9b82d026.css | 11836 ++++++++++++++++ dist/docs/README.md | 35 + dist/docs/VideoModal-overview.md | 82 + dist/docs/app-coordinators.md | 104 + dist/docs/capacitor-native-app-plan.md | 849 ++ dist/docs/events-cache-store-overview.md | 96 + dist/docs/moderation-service-overview.md | 73 + dist/docs/moderationService-overview.md | 99 + dist/docs/nip71-overview.md | 53 + dist/docs/nostrEventSchemas-overview.md | 86 + .../weekly-perf-report-2026-02-13.md | 50 + dist/docs/playbackService-overview.md | 75 + dist/docs/profileModalController-overview.md | 76 + ...weekly-race-condition-report-2026-02-14.md | 44 + dist/docs/scheduled-agent-prompts.md | 115 + dist/docs/smoke-test.md | 77 + .../testing/high-quality-playwright-tests.md | 148 + .../testing/playwright-function-coverage.md | 90 + ...-integration-recommendations-2026-02-22.md | 63 + dist/docs/webtorrent-architecture.md | 50 + dist/js/app/authSessionCoordinator.js | 1769 +++ dist/js/app/bindCoordinator.js | 22 + dist/js/app/feedCoordinator.js | 1766 +++ dist/js/app/modalCoordinator.js | 647 + dist/js/app/moderationCoordinator.js | 324 + dist/js/app/playbackCoordinator.js | 1216 ++ dist/js/app/routerCoordinator.js | 88 + dist/js/app/uiCoordinator.js | 321 + dist/js/embed.98945fd2b67db09c.js | 440 + dist/js/gridHealthLogic.js | 134 + dist/js/index.d1b55d32505a5ef6.js | 1408 ++ dist/js/nostr/commentTargetNormalizer.js | 982 ++ dist/js/nostr/decryptionSchemeCache.js | 70 + dist/js/nostr/eventsMap.js | 90 + dist/js/nostr/listEventOrdering.js | 70 + dist/js/nostr/managers/ConnectionManager.js | 965 ++ dist/js/nostr/managers/EventsCacheStore.js | 408 + dist/js/nostr/managers/PersistenceManager.js | 354 + dist/js/nostr/managers/SignerManager.js | 1134 ++ dist/js/nostr/nip46Connector.js | 1093 ++ dist/js/nostr/nip46LoggingUtils.js | 158 + dist/js/nostr/relayBatchFetcher.js | 248 + dist/js/nostr/relayConstants.js | 25 + dist/js/nostr/utils.js | 12 + dist/js/nostr/videoEventBuffer.js | 218 + dist/js/nostr/videoPayloadBuilder.js | 491 + dist/js/nostr/videoPublisher.js | 236 + .../nostrToolsBootstrap.8f9629740a8f3b78.js | 699 + dist/js/services/authUtils.js | 53 + dist/js/services/moderationUtils.js | 512 + dist/js/services/playbackStrategyService.js | 345 + dist/js/services/profileMetadataService.js | 294 + dist/js/services/relaySubscriptionService.js | 250 + dist/js/testHarness.js | 773 + .../ui/components/VideoModalSimilarHelpers.js | 344 + dist/js/ui/components/revertModalRenderers.js | 439 + .../video-modal/linkPreviewController.js | 309 + .../components/video-modal/zapController.js | 928 ++ dist/js/ui/creatorProfileController.js | 489 + dist/js/ui/dm/DMRelaySettings.js | 80 + dist/js/ui/dm/DMSettingsModalController.js | 261 + dist/js/ui/notificationController.js | 266 + .../ui/profileModal/ProfileAdminController.js | 885 ++ .../ui/profileModal/ProfileAdminRenderer.js | 283 + .../ProfileBlockListController.js | 617 + .../ProfileDirectMessageActions.js | 949 ++ .../ProfileDirectMessageController.js | 679 + .../ProfileDirectMessageHelper.js | 786 + .../ProfileDirectMessageRenderer.js | 911 ++ .../ui/profileModal/ProfileEditController.js | 311 + .../profileModal/ProfileHashtagController.js | 598 + .../ProfileModerationController.js | 932 ++ .../ui/profileModal/ProfileRelayController.js | 466 + .../profileModal/ProfileStorageController.js | 702 + .../profileModal/ProfileWalletController.js | 758 + dist/js/ui/profileModalContract.js | 916 ++ dist/js/ui/subscriptionHistoryController.js | 370 + dist/js/ui/thumbnailBinder.js | 92 + dist/js/ui/videoModalController.js | 393 + dist/js/ui/videoSettingsMenuController.js | 171 + dist/js/utils/asyncUtils.js | 130 + dist/js/utils/cryptoUtils.js | 69 + dist/js/utils/mime.js | 49 + dist/js/utils/nostrHelpers.js | 102 + dist/js/utils/pointerNormalization.js | 164 + dist/js/utils/simpleEventEmitter.js | 40 + dist/js/workers/exploreData.worker.js | 145 + dist/releases/draft-20260124.md | 17 + dist/releases/draft-20260131.md | 15 + dist/releases/draft-20260207.md | 26 + dist/releases/draft-20260212.md | 15 + dist/releases/draft-20260216.md | 15 + dist/views/dev/agent-dashboard.html | 114 + 97 files changed, 46855 insertions(+) create mode 100644 dist/asset-manifest.json create mode 100644 dist/components/dm-settings-modal.html create mode 100644 dist/components/subscription-history-modal.html create mode 100644 dist/css/docs.fe4863d7877544b1.css create mode 100644 dist/css/tailwind.generated.31c8693d9b82d026.css create mode 100644 dist/docs/README.md create mode 100644 dist/docs/VideoModal-overview.md create mode 100644 dist/docs/app-coordinators.md create mode 100644 dist/docs/capacitor-native-app-plan.md create mode 100644 dist/docs/events-cache-store-overview.md create mode 100644 dist/docs/moderation-service-overview.md create mode 100644 dist/docs/moderationService-overview.md create mode 100644 dist/docs/nip71-overview.md create mode 100644 dist/docs/nostrEventSchemas-overview.md create mode 100644 dist/docs/perf-reports/weekly-perf-report-2026-02-13.md create mode 100644 dist/docs/playbackService-overview.md create mode 100644 dist/docs/profileModalController-overview.md create mode 100644 dist/docs/race-condition-reports/weekly-race-condition-report-2026-02-14.md create mode 100644 dist/docs/scheduled-agent-prompts.md create mode 100644 dist/docs/smoke-test.md create mode 100644 dist/docs/testing/high-quality-playwright-tests.md create mode 100644 dist/docs/testing/playwright-function-coverage.md create mode 100644 dist/docs/testing/playwright-integration-recommendations-2026-02-22.md create mode 100644 dist/docs/webtorrent-architecture.md create mode 100644 dist/js/app/authSessionCoordinator.js create mode 100644 dist/js/app/bindCoordinator.js create mode 100644 dist/js/app/feedCoordinator.js create mode 100644 dist/js/app/modalCoordinator.js create mode 100644 dist/js/app/moderationCoordinator.js create mode 100644 dist/js/app/playbackCoordinator.js create mode 100644 dist/js/app/routerCoordinator.js create mode 100644 dist/js/app/uiCoordinator.js create mode 100644 dist/js/embed.98945fd2b67db09c.js create mode 100644 dist/js/gridHealthLogic.js create mode 100644 dist/js/index.d1b55d32505a5ef6.js create mode 100644 dist/js/nostr/commentTargetNormalizer.js create mode 100644 dist/js/nostr/decryptionSchemeCache.js create mode 100644 dist/js/nostr/eventsMap.js create mode 100644 dist/js/nostr/listEventOrdering.js create mode 100644 dist/js/nostr/managers/ConnectionManager.js create mode 100644 dist/js/nostr/managers/EventsCacheStore.js create mode 100644 dist/js/nostr/managers/PersistenceManager.js create mode 100644 dist/js/nostr/managers/SignerManager.js create mode 100644 dist/js/nostr/nip46Connector.js create mode 100644 dist/js/nostr/nip46LoggingUtils.js create mode 100644 dist/js/nostr/relayBatchFetcher.js create mode 100644 dist/js/nostr/relayConstants.js create mode 100644 dist/js/nostr/utils.js create mode 100644 dist/js/nostr/videoEventBuffer.js create mode 100644 dist/js/nostr/videoPayloadBuilder.js create mode 100644 dist/js/nostr/videoPublisher.js create mode 100644 dist/js/nostrToolsBootstrap.8f9629740a8f3b78.js create mode 100644 dist/js/services/authUtils.js create mode 100644 dist/js/services/moderationUtils.js create mode 100644 dist/js/services/playbackStrategyService.js create mode 100644 dist/js/services/profileMetadataService.js create mode 100644 dist/js/services/relaySubscriptionService.js create mode 100644 dist/js/testHarness.js create mode 100644 dist/js/ui/components/VideoModalSimilarHelpers.js create mode 100644 dist/js/ui/components/revertModalRenderers.js create mode 100644 dist/js/ui/components/video-modal/linkPreviewController.js create mode 100644 dist/js/ui/components/video-modal/zapController.js create mode 100644 dist/js/ui/creatorProfileController.js create mode 100644 dist/js/ui/dm/DMRelaySettings.js create mode 100644 dist/js/ui/dm/DMSettingsModalController.js create mode 100644 dist/js/ui/notificationController.js create mode 100644 dist/js/ui/profileModal/ProfileAdminController.js create mode 100644 dist/js/ui/profileModal/ProfileAdminRenderer.js create mode 100644 dist/js/ui/profileModal/ProfileBlockListController.js create mode 100644 dist/js/ui/profileModal/ProfileDirectMessageActions.js create mode 100644 dist/js/ui/profileModal/ProfileDirectMessageController.js create mode 100644 dist/js/ui/profileModal/ProfileDirectMessageHelper.js create mode 100644 dist/js/ui/profileModal/ProfileDirectMessageRenderer.js create mode 100644 dist/js/ui/profileModal/ProfileEditController.js create mode 100644 dist/js/ui/profileModal/ProfileHashtagController.js create mode 100644 dist/js/ui/profileModal/ProfileModerationController.js create mode 100644 dist/js/ui/profileModal/ProfileRelayController.js create mode 100644 dist/js/ui/profileModal/ProfileStorageController.js create mode 100644 dist/js/ui/profileModal/ProfileWalletController.js create mode 100644 dist/js/ui/profileModalContract.js create mode 100644 dist/js/ui/subscriptionHistoryController.js create mode 100644 dist/js/ui/thumbnailBinder.js create mode 100644 dist/js/ui/videoModalController.js create mode 100644 dist/js/ui/videoSettingsMenuController.js create mode 100644 dist/js/utils/asyncUtils.js create mode 100644 dist/js/utils/cryptoUtils.js create mode 100644 dist/js/utils/mime.js create mode 100644 dist/js/utils/nostrHelpers.js create mode 100644 dist/js/utils/pointerNormalization.js create mode 100644 dist/js/utils/simpleEventEmitter.js create mode 100644 dist/js/workers/exploreData.worker.js create mode 100644 dist/releases/draft-20260124.md create mode 100644 dist/releases/draft-20260131.md create mode 100644 dist/releases/draft-20260207.md create mode 100644 dist/releases/draft-20260212.md create mode 100644 dist/releases/draft-20260216.md create mode 100644 dist/views/dev/agent-dashboard.html diff --git a/dist/asset-manifest.json b/dist/asset-manifest.json new file mode 100644 index 00000000..d924060d --- /dev/null +++ b/dist/asset-manifest.json @@ -0,0 +1,7 @@ +{ + "css/docs.css": "css/docs.fe4863d7877544b1.css", + "css/tailwind.generated.css": "css/tailwind.generated.31c8693d9b82d026.css", + "js/embed.js": "js/embed.98945fd2b67db09c.js", + "js/index.js": "js/index.d1b55d32505a5ef6.js", + "js/nostrToolsBootstrap.js": "js/nostrToolsBootstrap.8f9629740a8f3b78.js" +} diff --git a/dist/components/dm-settings-modal.html b/dist/components/dm-settings-modal.html new file mode 100644 index 00000000..4de6b779 --- /dev/null +++ b/dist/components/dm-settings-modal.html @@ -0,0 +1,108 @@ +
diff --git a/dist/components/subscription-history-modal.html b/dist/components/subscription-history-modal.html new file mode 100644 index 00000000..a47d7cea --- /dev/null +++ b/dist/components/subscription-history-modal.html @@ -0,0 +1,111 @@ + diff --git a/dist/css/docs.fe4863d7877544b1.css b/dist/css/docs.fe4863d7877544b1.css new file mode 100644 index 00000000..8b833c45 --- /dev/null +++ b/dist/css/docs.fe4863d7877544b1.css @@ -0,0 +1,77 @@ +/* Docs layout + table of contents styling */ +#docsToc { + position: sticky; + top: var(--space-xl); + align-self: flex-start; + max-height: calc(100vh - var(--space-2xl)); + overflow-y: auto; + padding: var(--space-md); + border: var(--border-width-hairline) solid var(--border-subtle); + border-radius: var(--radius-lg); + background-color: var(--surface-sunken); + box-shadow: inset 0 0 0 var(--border-width-hairline) + var(--surface-overlay-darker); +} + +#docsContent { + min-width: 0; +} + +#docsContent .markdown-prose { + max-width: 72ch; +} + +#docsTocList, +#docsTocDrawerNav { + gap: var(--space-xs); +} + +#docsTocList ul, +#docsTocDrawerNav ul { + list-style: none; + margin: 0; + padding: 0; +} + +#docsTocList li, +#docsTocDrawerNav li { + margin: 0; +} + +#docsTocList [data-docs-toc-item], +#docsTocDrawerNav [data-docs-toc-item] { + display: block; + padding: var(--space-2xs) var(--space-xs); + border-radius: var(--radius-md); + color: var(--text-muted); + text-decoration: none; + transition: + background-color var(--motion-duration-fast) ease, + color var(--motion-duration-fast) ease; +} + +#docsTocList [data-docs-toc-item]:hover, +#docsTocDrawerNav [data-docs-toc-item]:hover, +#docsTocList [data-docs-toc-item]:focus-visible, +#docsTocDrawerNav [data-docs-toc-item]:focus-visible { + background-color: var(--surface-muted); + color: var(--text-primary); +} + +#docsTocList [data-docs-toc-item][aria-current="page"], +#docsTocDrawerNav [data-docs-toc-item][aria-current="page"] { + background-color: var(--surface-overlay-panel-soft); + color: var(--text-primary); +} + +#docsTocList [data-docs-toc-item]:focus-visible, +#docsTocDrawerNav [data-docs-toc-item]:focus-visible { + outline: var(--space-3xs) solid var(--color-accent); + outline-offset: var(--space-3xs); +} + +#docsTocDrawerNav { + max-height: calc(100vh - var(--space-2xl)); + overflow-y: auto; + padding-right: var(--space-2xs); +} diff --git a/dist/css/tailwind.generated.31c8693d9b82d026.css b/dist/css/tailwind.generated.31c8693d9b82d026.css new file mode 100644 index 00000000..4b0c2b58 --- /dev/null +++ b/dist/css/tailwind.generated.31c8693d9b82d026.css @@ -0,0 +1,11836 @@ +:root { + /* Semantic palette */ + --surface-base: var(--color-surface); + --surface-alt: var(--color-surface-alt); + --surface-raised: var(--color-card); + --surface-raised-private: var(--color-card-private); + --surface-raised-critical: var(--color-card-critical); + --surface-panel: var(--color-panel); + --surface-panel-hover: var(--color-panel-hover); + --surface-sunken: var(--color-surface-sunken); + --surface-muted: var(--color-surface-muted); + --surface-veil: var(--color-overlay-veil); + --surface-inverse: var(--color-page); + + --surface-overlay: var(--color-overlay); + --surface-overlay-muted: var(--color-overlay-muted); + --surface-overlay-strong: var(--color-overlay-strong); + --surface-overlay-darker: var(--color-overlay-darker); + --surface-overlay-black: var(--color-overlay-black); + --surface-overlay-banner-base: var(--color-page); + --surface-overlay-banner: var(--surface-overlay-banner-base); + --surface-overlay-banner-opaque: var(--surface-overlay-banner-base); + --surface-overlay-banner-strong: color-mix( + in srgb, + var(--surface-overlay-banner-base) 82%, + transparent + ); + --surface-overlay-banner-bottom: color-mix( + in srgb, + var(--surface-overlay-banner-base) 50%, + transparent + ); + --surface-overlay-banner-channel-mid: color-mix( + in srgb, + var(--surface-overlay-banner-base) 24%, + transparent + ); + --surface-overlay-banner-channel-faint: color-mix( + in srgb, + var(--surface-overlay-banner-base) 10%, + transparent + ); + --surface-overlay-banner-soft: color-mix( + in srgb, + var(--surface-overlay-banner-base) 56%, + transparent + ); + --surface-overlay-banner-faint: color-mix( + in srgb, + var(--surface-overlay-banner-base) 18%, + transparent + ); + --surface-overlay-banner-transparent: transparent; + --surface-overlay-banner-gradient-header: linear-gradient( + to bottom, + var(--surface-overlay-banner-opaque) 0%, + var(--surface-overlay-banner-strong) 38%, + var(--surface-overlay-banner-soft) 70%, + var(--surface-overlay-banner-faint) 88%, + var(--surface-overlay-banner-transparent) 100% + ); + --surface-overlay-banner-gradient-channel: linear-gradient( + to top, + var(--surface-overlay-banner-bottom) 0%, + var(--surface-overlay-banner-channel-mid) 28%, + var(--surface-overlay-banner-channel-faint) 42%, + var(--surface-overlay-banner-transparent) 50% + ); + --surface-overlay-banner-gradient: var( + --surface-overlay-banner-gradient-header + ); + --surface-overlay-panel: var(--color-overlay-panel); + --surface-overlay-panel-soft: var(--color-overlay-panel-soft); + --surface-overlay-panel-tint: var(--color-overlay-panel-tint); + --surface-overlay-panel-glass: var(--color-overlay-panel-glass); + --surface-overlay-panel-glass-soft: var(--color-overlay-panel-glass-soft); + --surface-modal-backdrop: var(--color-modal-backdrop); + --surface-modal: var(--color-modal-surface); + --blur-modal-backdrop: 18px; + --blur-modal-alert: 14px; + --blur-thumbnail-blur: 18px; + --modal-nav-backdrop-blur: 6px; + + --app-header-centerline-offset: calc( + var(--space-sm) + (var(--space-2xl-plus) / 2) + ); + --border-default: var(--color-border); + --border-subtle: var(--color-border-subtle); + --border-strong: var(--color-border-translucent-stronger); + --border-overlay: var(--color-border-translucent); + --border-overlay-strong: var(--color-border-translucent-strongest); + --border-overlay-glow: var(--color-border-translucent-glow); + --border-neutral-soft: var(--color-border-neutral-soft); + --border-info-soft: var(--color-border-info-soft); + --border-sidebar-strong: var(--color-border-sidebar-strong); + --border-width-hairline: 1px; + --border-width-fine: 0.5px; + + --text-primary: var(--color-text); + --text-inverse: var(--color-text-inverse); + --text-muted: var(--color-text-muted); + --text-muted-strong: var(--color-muted-strong); + --text-subtle: var(--color-subtle-text); + --text-frosted-primary: var(--color-text-frosted); + --text-frosted-strong: var(--color-text-frosted-strong); + --text-frosted-soft: var(--color-text-frosted-soft); + + --status-info: var(--color-info); + --status-info-strong: var(--color-info-strong); + --status-info-surface: var(--color-info-glass); + --status-info-border: var(--color-info-border); + --status-info-on: var(--color-info-on); + + --status-success: var(--color-success); + --status-success-strong: var(--color-success-strong); + --status-success-surface: var(--color-success-surface); + --status-success-border: var(--color-success-border); + --status-success-on: var(--color-success-on); + + --status-warning: var(--color-warning); + --status-warning-strong: var(--color-warning-strong); + --status-warning-surface: var(--color-warning-surface); + --status-warning-border: var(--color-warning-border); + --status-warning-on: var(--color-warning-on); + + --status-danger: var(--color-critical); + --status-danger-strong: var(--color-critical-strong); + --status-danger-surface: var(--color-danger-surface); + --status-danger-border: var(--color-danger-border); + --status-danger-on: var(--color-danger-on); + + --status-private: var(--color-private); + --status-private-strong: var(--color-private-strong); + --status-private-surface: var(--color-private-surface); + --status-private-border: var(--color-private-border); + --status-private-on: var(--color-private-on); + + --status-neutral: var(--color-muted); + --status-neutral-strong: var(--color-muted-strong); + --status-neutral-surface: var(--color-neutral-surface); + --status-neutral-border: var(--color-neutral-border); + --status-neutral-on: var(--color-neutral-on); + + /* Messaging & notifications */ + --message-bubble-background: var(--surface-sunken); + --message-bubble-border: var(--border-subtle); + --message-bubble-text: var(--text-primary); + --message-bubble-meta: var(--text-muted); + --message-bubble-outgoing-background: var(--surface-overlay-panel); + --message-bubble-outgoing-border: var(--border-overlay); + + --unread-badge-background: var(--status-info-strong); + --unread-badge-text: var(--text-inverse); + + --reply-highlight-background: var(--status-info-surface); + --reply-highlight-border: var(--status-info-border); + --reply-highlight-text: var(--status-info-on); + --reply-highlight-icon: var(--status-info-on); + + --notification-banner-accent: var(--color-accent-strong); + --notification-banner-accent-strong: var(--color-accent); + --notification-banner-border: var(--surface-overlay-panel-tint); + --notification-banner-background: var(--surface-overlay-panel); + --notification-banner-text: var(--text-primary); + --notification-banner-icon: var(--text-primary); + + --notification-banner-critical-accent: var(--status-danger-strong); + --notification-banner-critical-accent-strong: var(--status-danger); + --notification-banner-critical-border: var(--color-ring-critical-soft); + --notification-banner-critical-background: var(--surface-raised-critical); + --notification-banner-critical-text: var(--status-danger-on); + + --notification-banner-success-accent: var(--status-success-strong); + --notification-banner-success-accent-strong: var(--status-success); + --notification-banner-success-border: var(--status-success-border); + --notification-banner-success-background: var(--status-success-surface); + --notification-banner-success-text: var(--status-success-on); + + --notification-banner-info-accent: var(--status-info-strong); + --notification-banner-info-accent-strong: var(--status-info); + --notification-banner-info-border: var(--status-info-border); + --notification-banner-info-background: var(--status-info-surface); + --notification-banner-info-text: var(--status-info-on); + + --notification-banner-warning-accent: var(--status-warning-strong); + --notification-banner-warning-accent-strong: var(--status-warning); + --notification-banner-warning-border: var(--status-warning-border); + --notification-banner-warning-background: var(--status-warning-surface); + --notification-banner-warning-text: var(--status-warning-on); + + /* Layout & stacking */ + --scrollbar-width: 0.5rem; + --scrollbar-track: var(--color-white-soft); + --scrollbar-thumb: var(--color-white-softer); + --scrollbar-thumb-hover: var(--color-white-softest); + --z-app-header: 40; + --z-overlay-nav: 60; + --z-overlay-floating: 70; + --z-overlay-popover: 140; + --z-overlay-toast: 180; + --z-sidebar-overlay: 10; + --z-sidebar: 20; + --z-modal-root: 100; + --z-modal-overlay: 110; + --z-modal-content: 120; + --z-modal-player: 130; + --z-modal-top-root: 140; + --z-modal-top-overlay: 150; + --z-modal-top-content: 160; + --z-modal-peak-root: 165; + --z-modal-peak-overlay: 175; + --z-modal-peak-content: 185; + --z-modal-always-top: 200; + --overlay-backdrop-color: var(--color-overlay-backdrop); + --overlay-backdrop-blur: 12px; + --sidebar-width-expanded-base: 16rem; + --sidebar-dropup-content-width: 0px; + --sidebar-width-expanded: max( + var(--sidebar-width-expanded-base), + var(--sidebar-dropup-content-width) + ); + --sidebar-width-collapsed: 4rem; + --sidebar-width: var(--sidebar-width-expanded); + --sidebar-control-size: 2.75rem; + --sidebar-content-gap: 1rem; + --space-sidebar-shell-inline: var(--space-lg); + --space-sidebar-shell-block-start: var(--space-sm); + --space-sidebar-shell-block-end: 1.75rem; + --space-sidebar-scroll-gap: 1.75rem; + --space-sidebar-panel-gap: 1.35rem; + --space-sidebar-panel-padding-block: 1.35rem; + --space-sidebar-panel-padding-inline: 1.1rem; + --space-sidebar-footer-gap: 0.85rem; + --space-sidebar-trigger-padding-block: 0.78rem; + --space-sidebar-popover-offset: 0.85rem; + --space-sidebar-popover-padding-block: 0.85rem; + --space-sidebar-popover-padding-inline: 0.65rem; + --space-sidebar-popover-gap: 0.45rem; + --space-sidebar-dropup-scroll-reserve: calc( + var(--scrollbar-thin-width) + var(--space-sm) + var(--space-2xs) + ); + --sidebar-dropup-max-height: calc(3rem * 6); + --space-sidebar-nav-padding-block: 0.7rem; + --space-sidebar-nav-padding-inline-start: var(--space-xs); + --space-sidebar-nav-padding-inline-end: calc( + var(--space-lg) + var(--space-2xs) + ); + --space-sidebar-subnav-padding-block: 0.55rem; + --space-sidebar-nav-translate: 0.35rem; + --grid-card-min-width: 20rem; + /* Breakpoints (sync with Tailwind screen settings) */ + --breakpoint-lg: 64rem; + --popover-backdrop-blur: 12px; + --overlay-panel-radius: var(--radius-lg); + --overlay-panel-shadow: var(--shadow-lg); + --overlay-panel-padding-inline: var(--popup-padding-inline); + --overlay-panel-padding-block: var(--popup-padding-block); + --toast-translate: -1.5rem; + --sidebar-mobile-gutter: 3rem; + --popup-padding-inline: 1rem; + --popup-padding-block: 0.75rem; + --video-modal-primary-fr: 1.85fr; + --video-modal-secondary-min: 320px; + --video-modal-secondary-max: 35rem; + --video-modal-secondary-fr: 1fr; + --video-modal-layout-max: calc( + var(--layout-player-max-width) + var(--video-modal-secondary-max) + + var(--space-2xl-plus) + ); + --revert-modal-sidebar-min: 240px; + --revert-modal-sidebar-width: 280px; + --popover-inline-safe-max: calc(100vw - var(--space-xl)); + + /* Progress primitives */ + --progress-height-sm: 0.25rem; + --progress-height-md: 0.5rem; + --progress-radius: var(--radius-full); + --progress-track-color: var(--color-border-subtle); + --progress-fill-color: var(--color-info); + --progress-transition-duration: var(--motion-duration-fast); + --progress-transition-ease: var(--motion-ease-out); + + /* Spacing scale */ + --space-4xs: 0.0625rem; + --space-3xs: 0.125rem; + --space-2xs: 0.25rem; + --space-xs: 0.5rem; + --space-xs-snug: 0.4rem; + --space-sm: 0.75rem; + --space-md: 1rem; + --space-md-plus: 1.25rem; + --space-lg: 1.5rem; + --space-xl: 2rem; + --space-xl-compact: 2.25rem; + --space-xl-plus: 2.5rem; + --space-2xl: 3rem; + --space-2xl-plus: 3.5rem; + + /* Measurement primitives */ + --size-2px: 2px; + --size-3px: 3px; + --size-12px: 12px; + --size-24px: 24px; + --size-30px: 30px; + --size-32px: 32px; + --size-64px: 64px; + --size-80px: 80px; + --size-96px: 96px; + --size-128px: 128px; + --size-140px: 140px; + --size-168px: 168px; + --size-256px: 256px; + --size-5-75rem: 5.75rem; + --size-6rem: 6rem; + --size-7rem: 7rem; + --size-8rem: 8rem; + --size-12rem: 12rem; + --size-12-5rem: 12.5rem; + --size-14rem: 14rem; + --size-16rem: 16rem; + --size-18rem: 18rem; + --size-20rem: 20rem; + --size-28rem: 28rem; + --size-34rem: 34rem; + --size-40rem: 40rem; + --size-45rem: 45rem; + --size-70rem: 70rem; + + /* Border radii */ + --radius-sm: 0.25rem; + --radius-md: 0.5rem; + --radius-lg: 0.75rem; + --radius-xl: 1rem; + --radius-full: 9999px; + --radius-modal-xl: 1.75rem; + --radius-sidebar-shell: 1.5rem; + --radius-sidebar-panel: 1.1rem; + --radius-sidebar-nav: 0.95rem; + --radius-toggle-thumb: 0.5625rem; + + /* Component sizing */ + --menu-min-width: 12rem; + --header-search-max-inline: var(--size-34rem); + --modal-max-width: 62.5rem; + --modal-sheet-inline-max: var(--modal-max-width); + --modal-shell-max-height: 90vh; + --modal-sheet-max-height: 92vh; + --modal-body-max-height: calc(92vh - 4rem); + --profile-modal-inline-max: var(--size-70rem); + --player-modal-module-scroll-min-height: var(--size-14rem); + --player-modal-module-scroll-max-height: var(--size-28rem); + --modal-pane-max-height: 48vh; + --modal-pane-min-height: 20rem; + --moderation-badge-max-inline: var(--size-28rem); + --notification-banner-max-inline: var(--size-28rem); + --profile-modal-nav-min-width: max-content; + --profile-modal-nav-max-width: max-content; + --profile-modal-scrollbar-offset: var(--space-2xs); + --modal-embed-height: 80vh; + --profile-history-max-height: 26.25rem; + --comment-avatar-size: var(--space-xl-plus); + --comment-composer-min-height: var(--size-7rem); + --video-modal-reaction-label-min-inline: var(--size-6rem); + --video-modal-item-media-min: var(--size-5-75rem); + --video-modal-item-media-max: var(--size-8rem); + --video-card-compact-media-min: var(--size-8rem); + --video-card-compact-media-max: var(--size-12-5rem); + --similar-card-media-width: var(--size-168px); + --similar-card-media-width-sm: var(--size-140px); + --docs-popover-scroll-height: var(--size-45rem); + --profile-modal-active-min-width: var(--size-12rem); + --status-log-min-height: 5rem; + --layout-player-max-width: 68.75rem; + --layout-docs-max-width: 92.5rem; + --icon-size-sm: var(--font-size-lg); + --icon-size-md: var(--space-md-plus); + --icon-size-lg: var(--space-xl-plus); + --avatar-size-lg: var(--space-2xl-plus); + --form-textarea-min-height: 8rem; + --scrollbar-thin-width: 0.4rem; + --modal-progress-height: calc(var(--space-3xs) * 3); + --video-modal-action-min-width: 2.75rem; + --outline-thick-width: 0.1875rem; + --icon-button-ring-width: var(--outline-thick-width); + + /* Form controls */ + --form-select-icon-offset: var(--space-sm); + --form-select-icon-gap: var(--space-xs-snug); + --form-select-icon-hit-area: var(--space-xl-plus); + --form-select-icon-size: 0.6rem; + --form-select-divider-width: var(--border-width-hairline); + --form-checkbox-checkmark-offset: calc(var(--space-3xs) * -1); + + /* Utility measurements */ + --breakpoint-edge-offset: 0.02px; + --offscreen-offset: -9999px; + + /* Motion */ + --motion-card-enter-translate: var(--space-xs); + --motion-fade-in-translate: var(--space-md-plus); + --motion-login-option-hover-translate: calc(var(--size-3px) * -1); + --motion-video-card-hover-translate: -0.35rem; + --motion-video-card-backdrop-translate: 0.15rem; + + /* Shadows */ + --shadow-sm: 0 0.0625rem 0.125rem 0 var(--color-shadow-floating); + --shadow-md: 0 0.25rem 0.375rem -0.0625rem var(--color-shadow-floating); + --shadow-lg: 0 0.625rem 0.9375rem -0.1875rem var(--color-shadow-elevated); + --shadow-badge-offset-y: var(--size-12px); + --shadow-badge-blur: var(--size-30px); + --shadow-notification-offset-y: var(--size-32px); + --shadow-notification-blur: var(--size-64px); + --shadow-modal: 0 2.75rem 6rem -1.25rem var(--color-shadow-modal); + --shadow-sidebar-shell: 0 1.875rem 3.75rem -1.5rem var(--color-shadow-sidebar); + --shadow-sidebar-accent: 0 1.65rem 3.25rem -1.35rem var(--color-sidebar-glow); + --shadow-sidebar-trigger: 0 1.25rem 2.5rem -1.35rem var(--color-shadow-panel); + --shadow-sidebar-dropup: 0 1.75rem 3.25rem -1.45rem var(--color-sidebar-glow); + --shadow-sidebar-panel: 0 2.25rem 4.5rem -1.85rem var(--color-shadow-sidebar); + --shadow-sidebar-focus-ring: + 0 0 0 0.125rem var(--color-sidebar-glow), + 0 0 0 0.25rem var(--color-sidebar-hover-strong); + --shadow-popover-zap: 0 22px 48px -18px var(--color-shadow-intense); + --shadow-video-modal: 0 1rem 2.25rem var(--color-shadow-elevated); + --blur-video-card-backdrop-strong: var(--size-24px); + --video-modal-ambient-blur-min: var(--size-128px); + --video-modal-ambient-blur-max: var(--size-256px); + + /* Typography */ + --font-family-sans: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif; + --font-family-mono: "Fira Code", "SFMono-Regular", ui-monospace, monospace; + --font-size-4xs: 0.65rem; + --font-size-3xs: 0.6875rem; + --font-size-2xs: 0.7rem; + --font-size-xs: 0.75rem; + --font-size-sm: 0.875rem; + --font-size-base: 1rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.5rem; + --font-size-2xl: 2rem; + --font-size-xl-plus: 1.875rem; + --font-size-modal-title-base: 1.25rem; + --font-size-sidebar-nav: 0.95rem; + --font-size-sidebar-subnav: 0.85rem; + --font-size-sidebar-trigger: 0.9rem; + --link-underline-thickness: var(--size-2px); + --line-height-tight: 1.1; + --line-height-snug: 1.25; + --line-height-base: 1.5; + --line-height-relaxed: 1.75; + --tracking-extra-wide: 0.2em; + + /* Beacon UI tokens */ + --grid-border-width: calc(var(--space-2xs) / 4); + --grid-canvas-padding-top: var(--grid-border-width); + --grid-viewport-min-height: calc(var(--space-xl) - var(--space-sm)); + --grid-cell-padding-block: var(--space-sm); + --grid-cell-padding-inline: var(--space-md); + --grid-header-font-size: var(--font-size-xs); + --grid-header-letter-spacing: 0.08em; + --grid-overlay-margin: 10%; + --grid-overlay-padding-block: var(--space-md); + --grid-overlay-padding-inline: var(--space-xl); + --grid-overlay-radius: var(--radius-lg); + --grid-overlay-font-size: var(--font-size-lg); + --grid-overlay-text-opacity: 0.66; + --grid-resizer-width: calc(var(--space-2xs) * 1.25); + --grid-resize-overlay-width: var(--grid-border-width); + --grid-sort-indicator-size: calc(var(--space-lg) - var(--space-2xs)); + --grid-sort-indicator-offset: var(--space-xs); + --grid-sort-indicator-stroke: calc(var(--space-2xs) / 2); + --grid-sort-indicator-thickness: var(--grid-border-width); + --notify-padding-block: var(--space-md); + --notify-padding-inline: var(--space-2xl); + --notify-font-size: var(--font-size-base); + --notify-dismiss-size: calc(var(--space-xl) + var(--space-xs)); + --notify-dismiss-size-compact: calc(var(--space-lg) + var(--space-2xs)); + --notify-dismiss-font-size: var(--font-size-sm); + --notify-dismiss-radius: var(--radius-full); + --notify-dismiss-color: var(--color-subtle); + --notify-dismiss-background: var(--color-overlay-panel); + --notify-dismiss-background-hover: var(--color-overlay-panel-soft); + --z-notify: 1200; + + /* Motion */ + --motion-duration-fast: 120ms; + --motion-duration-base: 160ms; + --motion-duration-slow: 280ms; + --motion-ease-out: cubic-bezier(0.16, 1, 0.3, 1); + --motion-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); + --modal-motion-duration: var(--motion-duration-base); +} +:root[data-theme="light"] { + /* Light theme palette */ + --color-page: rgb(247 248 252); + --color-page-alt: rgb(242 244 248); + --color-surface: rgb(255 255 255); + --color-surface-alt: rgb(248 250 252); + --color-bg: var(--color-surface); + --color-card: rgb(255 255 255); + --color-card-private: rgb(243 236 255); + --color-card-critical: rgb(255 236 238); + --color-panel: rgb(252 253 255); + --color-panel-hover: rgb(239 242 249); + --color-border: rgb(210 219 236); + --color-border-subtle: rgb(229 234 242); + + --color-accent: rgb(99 102 241); + --color-accent-strong: rgb(79 70 229); + --color-accent-pressed: rgb(67 56 202); + --color-accent-override: rgb(84 0 17); + --color-accent-strong-override: rgb(254 0 50); + --color-accent-pressed-override: rgb(169 0 33); + --color-primary: var(--color-accent-strong); + --color-secondary: var(--color-accent); + + --color-logo-accent: var(--color-accent-strong); + --color-logo-wordmark: rgb(40 54 77); + --color-logo-wordmark-inverse: var(--color-white); + --color-logo-background: rgb(15 23 42); + --color-logo-background-inverse: var(--color-white); + + --color-info: rgb(59 130 246); + --color-info-strong: rgb(37 99 235); + --color-info-pressed: rgb(29 78 216); + --color-info-glass: rgb(59 130 246 / 0.14); + --color-info-border: rgb(59 130 246 / 0.35); + --color-info-on: rgb(227 242 255); + + --color-muted-strong: rgb(71 85 105); + --color-text: rgb(24 31 44); + --color-text-strong: rgb(12 16 26); + --color-text-inverse: rgb(255 255 255); + --color-text-muted: rgb(102 112 133); + --color-muted: rgb(136 146 166); + --color-muted-alt: rgb(120 130 150); + --color-subtle-text: rgb(136 146 166); + --color-subtle: rgb(243 245 250); + --color-surface-sunken: rgb(232 235 244); + --color-surface-muted: rgb(236 240 249); + + --color-critical: rgb(220 54 70); + --color-critical-strong: rgb(185 32 55); + --color-danger-surface: rgb(252 226 230); + --color-danger-border: rgb(220 54 70 / 0.35); + --color-danger-on: rgb(96 18 31); + + --color-warning: rgb(234 179 8); + --color-warning-strong: rgb(202 138 4); + --color-warning-surface: rgb(253 224 71 / 0.35); + --color-warning-border: rgb(234 179 8 / 0.35); + --color-warning-glass: rgb(253 224 71 / 0.18); + --color-warning-on: rgb(92 55 2); + + --color-success: rgb(22 163 74); + --color-success-strong: rgb(21 128 61); + --color-success-surface: rgb(222 250 236); + --color-success-border: rgb(34 197 94 / 0.3); + --color-success-on: rgb(18 84 48); + + --color-private: rgb(139 92 246); + --color-private-strong: rgb(124 58 237); + --color-private-surface: rgb(237 233 254); + --color-private-border: rgb(139 92 246 / 0.32); + --color-private-on: rgb(74 29 150); + + --color-neutral-700: rgb(71 85 105); + --color-neutral-600: rgb(102 112 133); + --color-neutral-surface: rgb(232 236 244); + --color-neutral-border: rgb(205 213 226); + --color-neutral-on: rgb(62 72 92); + + --color-white: rgb(255 255 255); + --color-black: rgb(0 0 0); + + --color-overlay: rgb(15 23 42 / 0.3); + --color-overlay-black: rgb(15 23 42 / 0.7); + --color-overlay-muted: rgb(60 75 105 / 0.18); + --color-overlay-strong: rgb(15 23 42 / 0.56); + --color-overlay-darker: rgb(12 18 32 / 0.68); + --color-overlay-panel: rgb(248 250 255 / 0.92); + --color-overlay-panel-soft: rgb(244 247 255 / 0.78); + --color-overlay-panel-tint: rgb(146 170 211 / 0.24); + --color-overlay-panel-glass: rgb(255 255 255 / 0.85); + --color-overlay-panel-glass-soft: rgb(246 249 255 / 0.7); + --color-overlay-panel-gradient-start: rgb(255 255 255 / 0.95); + --color-overlay-panel-gradient-end: rgb(232 236 244 / 0.92); + --color-modal-backdrop: rgb(15 23 42 / 0.28); + --color-modal-surface: rgb(255 255 255 / 0.94); + --color-overlay-veil: rgb(103 112 133 / 0.45); + --color-overlay-banner-bottom: rgb(255 255 255 / 0.6); + --color-overlay-banner-transparent: rgb(255 255 255 / 0); + --color-overlay-backdrop: rgb(15 23 42 / 0.2); + + --scrollbar-track: color-mix( + in srgb, + var(--color-sidebar-border-strong) 40%, + transparent + ); + --scrollbar-thumb: color-mix(in srgb, var(--color-accent) 64%, transparent); + --scrollbar-thumb-hover: color-mix( + in srgb, + var(--color-accent-strong) 76%, + transparent + ); + + --color-sidebar-surface: rgb(255 255 255 / 0.9); + --color-sidebar-surface-alt: rgb(236 240 247 / 0.72); + --color-sidebar-border: rgb(184 194 212 / 0.28); + --color-sidebar-border-strong: rgb(148 163 184 / 0.36); + --color-sidebar-hover: color-mix( + in srgb, + var(--color-accent) 16%, + transparent + ); + --color-sidebar-hover-strong: color-mix( + in srgb, + var(--color-accent-strong) 24%, + transparent + ); + --color-sidebar-glow: color-mix( + in srgb, + var(--color-accent) 36%, + transparent + ); + --color-sidebar-accent-start: color-mix( + in srgb, + var(--color-accent-strong) 88%, + transparent + ); + --color-sidebar-accent-end: color-mix( + in srgb, + var(--color-accent) 82%, + transparent + ); + --color-sidebar-text-muted: var(--color-text-muted); + --sidebar-icon-filter: brightness(0) saturate(100%); + + --color-surface-tint-subtle: rgb(15 23 42 / 0.08); + --color-border-translucent: rgb(148 163 184 / 0.18); + --color-border-translucent-strong: rgb(148 163 184 / 0.22); + --color-border-translucent-bright: rgb(148 163 184 / 0.28); + --color-border-translucent-stronger: rgb(148 163 184 / 0.32); + --color-border-translucent-strongest: rgb(148 163 184 / 0.36); + --color-border-translucent-glow: rgb(148 163 184 / 0.45); + --color-border-translucent-medium: rgb(148 163 184 / 0.2); + --color-border-neutral-soft: rgb(148 163 184 / 0.25); + --color-border-info-soft: rgb(59 130 246 / 0.32); + --color-border-sidebar-strong: rgb(102 112 133 / 0.75); + + --color-ring-private: rgb(139 92 246 / 0.5); + --color-ring-private-hover: rgb(168 85 247 / 0.6); + --color-ring-critical: rgb(220 54 70 / 0.35); + --color-ring-critical-soft: rgb(220 54 70 / 0.3); + --color-ring-critical-hover: rgb(220 54 70 / 0.4); + --color-ring-critical-strong: rgb(220 54 70 / 0.5); + --color-ring-alert: rgb(239 68 68 / 0.48); + + --color-gradient-visibility-start: rgb(99 102 241 / 0.28); + --color-gradient-visibility-end: rgb(129 140 248 / 0.24); + + --color-white-soft: rgb(255 255 255 / 0.08); + --color-white-softer: rgb(255 255 255 / 0.24); + --color-white-softest: rgb(255 255 255 / 0.32); + + --color-shadow-floating: rgb(15 23 42 / 0.18); + --color-shadow-elevated: rgb(15 23 42 / 0.16); + --color-shadow-panel: rgb(15 23 42 / 0.12); + --color-shadow-notification: rgb(15 23 42 / 0.14); + --color-shadow-intense: rgb(15 23 42 / 0.22); + --color-shadow-sidebar: rgb(15 23 42 / 0.28); + --color-shadow-modal: rgb(15 23 42 / 0.28); + + --color-divider-strong: rgb(203 213 225 / 0.6); + --color-text-frosted-strong: rgb(40 54 77 / 0.85); + --color-text-frosted: rgb(61 74 98 / 0.8); + --color-text-frosted-soft: rgb(82 96 122 / 0.72); +} +:root[data-theme="dark"], +:root:not([data-theme]) { + /* Dark theme palette */ + --color-page: rgb(6 10 18); + --color-page-alt: rgb(8 12 22); + --color-surface: rgb(10 14 26); + --color-surface-alt: rgb(14 20 34); + --color-bg: var(--color-surface); + --color-card: rgb(18 26 44); + --color-card-private: rgb(38 28 62); + --color-card-critical: rgb(58 20 28); + --color-panel: rgb(16 24 40); + --color-panel-hover: rgb(24 34 52); + --color-border: rgb(61 80 112); + --color-border-subtle: rgb(38 52 76); + + --color-accent: rgb(129 140 248); + --color-accent-strong: rgb(99 102 241); + --color-accent-pressed: rgb(79 70 229); + --color-accent-override: rgb(84 0 17); + --color-accent-strong-override: rgb(254 0 50); + --color-accent-pressed-override: rgb(169 0 33); + --color-primary: var(--color-accent-strong); + --color-secondary: rgb(56 189 248); + + --color-logo-accent: var(--color-accent-strong); + --color-logo-wordmark: rgb(198 207 222); + --color-logo-wordmark-inverse: var(--color-white); + --color-logo-background: rgb(12 18 30); + --color-logo-background-inverse: var(--color-white); + + --color-info: rgb(96 165 250); + --color-info-strong: rgb(56 132 255); + --color-info-pressed: rgb(37 99 235); + --color-info-glass: rgb(56 132 255 / 0.22); + --color-info-border: rgb(96 165 250 / 0.42); + --color-info-on: rgb(235 244 255); + + --color-muted-strong: rgb(206 215 232); + --color-text: rgb(226 232 240); + --color-text-strong: rgb(244 247 255); + --color-text-inverse: rgb(12 18 30); + --color-text-muted: rgb(165 179 201); + --color-muted: rgb(148 163 184); + --color-muted-alt: rgb(128 139 162); + --color-subtle-text: rgb(168 180 205); + --color-subtle: rgb(28 38 58); + --color-surface-sunken: rgb(13 19 32 / 0.92); + --color-surface-muted: rgb(18 26 44 / 0.82); + + --color-critical: rgb(239 83 98); + --color-critical-strong: rgb(220 38 38); + --color-danger-surface: rgb(220 38 38 / 0.28); + --color-danger-border: rgb(220 38 38 / 0.45); + --color-danger-on: rgb(255 228 233); + + --color-warning: rgb(250 204 21); + --color-warning-strong: rgb(234 179 8); + --color-warning-surface: rgb(253 224 71 / 0.22); + --color-warning-border: rgb(250 204 21 / 0.42); + --color-warning-glass: rgb(253 224 71 / 0.2); + --color-warning-on: rgb(26 18 0); + + --color-success: rgb(34 197 94); + --color-success-strong: rgb(22 163 74); + --color-success-surface: rgb(22 163 74 / 0.24); + --color-success-border: rgb(34 197 94 / 0.45); + --color-success-on: rgb(210 252 228); + + --color-private: rgb(168 85 247); + --color-private-strong: rgb(139 92 246); + --color-private-surface: rgb(124 58 237 / 0.26); + --color-private-border: rgb(168 85 247 / 0.45); + --color-private-on: rgb(239 230 255); + + --color-neutral-700: rgb(58 75 110); + --color-neutral-600: rgb(90 105 133); + --color-neutral-surface: rgb(99 114 144 / 0.24); + --color-neutral-border: rgb(99 114 144 / 0.35); + --color-neutral-on: rgb(210 220 238); + + --color-white: rgb(255 255 255); + --color-black: rgb(0 0 0); + + --color-overlay: rgb(8 11 20 / 0.72); + --color-overlay-black: rgb(0 0 0 / 0.88); + --color-overlay-muted: rgb(12 18 30 / 0.6); + --color-overlay-strong: rgb(8 12 24 / 0.82); + --color-overlay-darker: rgb(5 8 16 / 0.9); + --color-overlay-panel: rgb(14 20 34 / 0.92); + --color-overlay-panel-soft: rgb(18 26 42 / 0.78); + --color-overlay-panel-tint: rgb(56 93 160 / 0.36); + --color-overlay-panel-glass: rgb(14 24 42 / 0.86); + --color-overlay-panel-glass-soft: rgb(16 28 48 / 0.72); + --color-overlay-panel-gradient-start: rgb(18 26 44 / 0.92); + --color-overlay-panel-gradient-end: rgb(10 16 30 / 0.92); + --color-modal-backdrop: rgb(5 8 14 / 0.68); + --color-modal-surface: rgb(14 22 38 / 0.88); + --color-overlay-veil: rgb(4 6 12 / 0.94); + --color-overlay-banner-bottom: rgb(0 0 0 / 0.6); + --color-overlay-banner-transparent: rgb(0 0 0 / 0); + --color-overlay-backdrop: rgb(5 8 14 / 0.75); + + --scrollbar-track: color-mix( + in srgb, + var(--color-sidebar-surface-alt) 54%, + transparent + ); + --scrollbar-thumb: color-mix(in srgb, var(--color-accent) 72%, transparent); + --scrollbar-thumb-hover: color-mix( + in srgb, + var(--color-accent-strong) 84%, + transparent + ); + + --color-sidebar-surface: rgb(12 18 30 / 0.94); + --color-sidebar-surface-alt: rgb(10 18 32 / 0.8); + --color-sidebar-border: rgb(86 106 142 / 0.26); + --color-sidebar-border-strong: rgb(112 133 170 / 0.42); + --color-sidebar-hover: color-mix( + in srgb, + var(--color-accent) 22%, + transparent + ); + --color-sidebar-hover-strong: color-mix( + in srgb, + var(--color-accent-strong) 32%, + transparent + ); + --color-sidebar-glow: color-mix( + in srgb, + var(--color-accent) 42%, + transparent + ); + --color-sidebar-accent-start: color-mix( + in srgb, + var(--color-accent) 92%, + transparent + ); + --color-sidebar-accent-end: color-mix( + in srgb, + var(--color-accent-strong) 88%, + transparent + ); + --color-sidebar-text-muted: var(--color-text-muted); + --sidebar-icon-filter: brightness(0) invert(1); + + --color-surface-tint-subtle: rgb(94 113 161 / 0.12); + --color-border-translucent: rgb(99 114 144 / 0.22); + --color-border-translucent-strong: rgb(110 130 170 / 0.28); + --color-border-translucent-bright: rgb(148 163 184 / 0.35); + --color-border-translucent-stronger: rgb(148 163 184 / 0.38); + --color-border-translucent-strongest: rgb(198 207 222 / 0.45); + --color-border-translucent-glow: rgb(129 140 248 / 0.55); + --color-border-translucent-medium: rgb(99 114 144 / 0.28); + --color-border-neutral-soft: rgb(99 114 144 / 0.3); + --color-border-info-soft: rgb(96 165 250 / 0.35); + --color-border-sidebar-strong: rgb(32 46 68 / 0.88); + + --color-ring-private: rgb(168 85 247 / 0.55); + --color-ring-private-hover: rgb(192 132 252 / 0.65); + --color-ring-critical: rgb(239 83 98 / 0.42); + --color-ring-critical-soft: rgb(239 83 98 / 0.35); + --color-ring-critical-hover: rgb(239 83 98 / 0.5); + --color-ring-critical-strong: rgb(220 38 38 / 0.6); + --color-ring-alert: rgb(220 38 38 / 0.6); + + --color-gradient-visibility-start: rgb(129 140 248 / 0.4); + --color-gradient-visibility-end: rgb(192 132 252 / 0.32); + + --color-white-soft: rgb(255 255 255 / 0.1); + --color-white-softer: rgb(255 255 255 / 0.3); + --color-white-softest: rgb(255 255 255 / 0.4); + + --color-shadow-floating: rgb(8 11 30 / 0.55); + --color-shadow-elevated: rgb(8 11 30 / 0.45); + --color-shadow-panel: rgb(15 23 42 / 0.35); + --color-shadow-notification: rgb(15 23 42 / 0.3); + --color-shadow-intense: rgb(250 204 21 / 0.48); + --color-shadow-sidebar: rgb(0 0 0 / 0.45); + --color-shadow-modal: rgb(8 11 30 / 0.55); + + --color-divider-strong: rgb(15 23 42 / 0.35); + --color-text-frosted-strong: rgb(226 232 240 / 0.94); + --color-text-frosted: rgb(226 232 240 / 0.9); + --color-text-frosted-soft: rgb(226 232 240 / 0.82); +} +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; + --tw-contain-size: ; + --tw-contain-layout: ; + --tw-contain-paint: ; + --tw-contain-style: ; +} +/* ! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com */ +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ +*, +::before, +::after { + box-sizing: border-box; /* 1 */ + border-width: 0; /* 2 */ + border-style: solid; /* 2 */ + border-color: #e5e7eb; /* 2 */ +} +::before, +::after { + --tw-content: ''; +} +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +7. Disable tap highlights on iOS +*/ +html, +:host { + line-height: 1.5; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -moz-tab-size: 4; /* 3 */ + -o-tab-size: 4; + tab-size: 4; /* 3 */ + font-family: var(--font-family-sans); /* 4 */ + font-feature-settings: normal; /* 5 */ + font-variation-settings: normal; /* 6 */ + -webkit-tap-highlight-color: transparent; /* 7 */ +} +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ +body { + margin: 0; /* 1 */ + line-height: inherit; /* 2 */ +} +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ +hr { + height: 0; /* 1 */ + color: inherit; /* 2 */ + border-top-width: 1px; /* 3 */ +} +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} +/* +Remove the default font size and weight for headings. +*/ +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ +a { + color: inherit; + text-decoration: inherit; +} +/* +Add the correct font weight in Edge and Safari. +*/ +b, +strong { + font-weight: bolder; +} +/* +1. Use the user's configured `mono` font-family by default. +2. Use the user's configured `mono` font-feature-settings by default. +3. Use the user's configured `mono` font-variation-settings by default. +4. Correct the odd `em` font sizing in all browsers. +*/ +code, +kbd, +samp, +pre { + font-family: var(--font-family-mono); /* 1 */ + font-feature-settings: normal; /* 2 */ + font-variation-settings: normal; /* 3 */ + font-size: 1em; /* 4 */ +} +/* +Add the correct font size in all browsers. +*/ +small { + font-size: 80%; +} +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ +table { + text-indent: 0; /* 1 */ + border-color: inherit; /* 2 */ + border-collapse: collapse; /* 3 */ +} +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-feature-settings: inherit; /* 1 */ + font-variation-settings: inherit; /* 1 */ + font-size: 100%; /* 1 */ + font-weight: inherit; /* 1 */ + line-height: inherit; /* 1 */ + letter-spacing: inherit; /* 1 */ + color: inherit; /* 1 */ + margin: 0; /* 2 */ + padding: 0; /* 3 */ +} +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ +button, +select { + text-transform: none; +} +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ +button, +input:where([type='button']), +input:where([type='reset']), +input:where([type='submit']) { + -webkit-appearance: button; /* 1 */ + background-color: transparent; /* 2 */ + background-image: none; /* 2 */ +} +/* +Use the modern Firefox focus style for all focusable elements. +*/ +:-moz-focusring { + outline: auto; +} +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ +:-moz-ui-invalid { + box-shadow: none; +} +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ +progress { + vertical-align: baseline; +} +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ +[type='search'] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ +::-webkit-search-decoration { + -webkit-appearance: none; +} +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} +/* +Add the correct display in Chrome and Safari. +*/ +summary { + display: list-item; +} +/* +Removes the default spacing and border for appropriate elements. +*/ +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} +fieldset { + margin: 0; + padding: 0; +} +legend { + padding: 0; +} +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} +/* +Reset default styling for dialogs. +*/ +dialog { + padding: 0; +} +/* +Prevent resizing textareas horizontally by default. +*/ +textarea { + resize: vertical; +} +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; /* 1 */ + color: #9ca3af; /* 2 */ +} +input::placeholder, +textarea::placeholder { + opacity: 1; /* 1 */ + color: #9ca3af; /* 2 */ +} +/* +Set the default cursor for buttons. +*/ +button, +[role="button"] { + cursor: pointer; +} +/* +Make sure disabled buttons don't get the pointer cursor. +*/ +:disabled { + cursor: default; +} +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; /* 1 */ + vertical-align: middle; /* 2 */ +} +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ +img, +video { + max-width: 100%; + height: auto; +} +/* Make elements with the HTML hidden attribute stay hidden by default */ +[hidden]:where(:not([hidden="until-found"])) { + display: none; +} +html { + font-size: 80%; + } +@media (min-width: 768px) { + html { + font-size: 100%; + } + } +@media (min-width: 1024px) { + html { + font-size: 75%; + } + } +*, + *::before, + *::after { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); + } +*::-webkit-scrollbar { + width: var(--scrollbar-width); + height: var(--scrollbar-width); + } +*::-webkit-scrollbar-track { + background: var(--scrollbar-track); + } +*::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb); + border-radius: var(--radius-sm); + } +*::-webkit-scrollbar-thumb:hover { + background: var(--scrollbar-thumb-hover); + } +body { + --app-header-centerline: calc( + env(safe-area-inset-top, 0) + var(--app-header-centerline-offset) + ); + font-family: var(--font-family-sans); + background-color: var(--color-page); + color: var(--color-text-strong); + line-height: 1.5; + margin: 0; + padding: 0; + overflow-x: hidden; + } +:root[data-theme-accent="override"] { + --color-accent: var(--color-accent-override); + --color-accent-strong: var(--color-accent-strong-override); + --color-accent-pressed: var(--color-accent-pressed-override); + } +#uiOverlay { + position: fixed; + inset: 0; + pointer-events: none; + z-index: var(--z-overlay-popover); + } +#uiOverlay > * { + pointer-events: auto; + } +#nip71TagsFieldset > legend, + #editNip71TagsFieldset > legend { + margin-left: 0; + padding: 0; + } +#app { + background-color: var(--color-page); + color: inherit; + } +html.modal-open, + body.modal-open { + overflow: hidden; + height: 100%; + } +body.modal-open #app { + overflow: hidden; + } +body.modal-open #sidebar { + pointer-events: none; + opacity: 0; + visibility: hidden; + z-index: var(--z-sidebar-overlay); + } +[ng\:cloak], + [ng-cloak], + [data-ng-cloak], + [x-ng-cloak], + .ng-cloak, + .x-ng-cloak, + .ng-hide:not(.ng-hide-animate) { + display: none !important; + } +ng\:form { + display: block; + } +.\!container { + width: 100% !important; +} +.container { + width: 100%; +} +@media (min-width: 400px) { + .\!container { + max-width: 400px !important; + } + .container { + max-width: 400px; + } +} +@media (min-width: 480px) { + .\!container { + max-width: 480px !important; + } + .container { + max-width: 480px; + } +} +@media (min-width: 640px) { + .\!container { + max-width: 640px !important; + } + .container { + max-width: 640px; + } +} +@media (min-width: 768px) { + .\!container { + max-width: 768px !important; + } + .container { + max-width: 768px; + } +} +@media (min-width: 1024px) { + .\!container { + max-width: 1024px !important; + } + .container { + max-width: 1024px; + } +} +@media (min-width: 1280px) { + .\!container { + max-width: 1280px !important; + } + .container { + max-width: 1280px; + } +} +@media (min-width: 1536px) { + .\!container { + max-width: 1536px !important; + } + .container { + max-width: 1536px; + } +} +.ds-header { + display: flex; + align-items: center; + justify-content: flex-start; + padding-top: var(--space-sm); + padding-bottom: var(--space-sm); +} +.app-shell__header { + position: sticky; + top: env(safe-area-inset-top, 0); + z-index: var(--z-app-header); + padding-top: calc(var(--space-sm) + env(safe-area-inset-top, 0)); + padding-bottom: var(--space-sm); + background-color: transparent; + background-image: var(--surface-overlay-banner-gradient-header); + background-repeat: no-repeat; + background-size: 100% 100%; + } +.ds-metric-probe { + position: absolute; + top: 0; + left: 0; + visibility: hidden; + pointer-events: none; + contain: layout size style; + inline-size: 0; + block-size: var(--ds-metric-probe-length, 0); + overflow: hidden; + } +.ds-header__logo { + height: var(--space-2xl-plus); + width: auto; + max-width: none; +} +.focus-ring { + outline: 2px solid transparent; + outline-offset: 2px; +} +.focus-ring:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.author-pic { + display: block; + height: 100%; + width: 100%; + border-radius: var(--radius-full); + -o-object-fit: cover; + object-fit: cover; +} +.header-icon-toggle { + outline: 2px solid transparent; + outline-offset: 2px; +} +.header-icon-toggle:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.header-icon-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + width: var(--icon-size-lg); + height: var(--icon-size-lg); + min-width: var(--icon-size-lg); + min-height: var(--icon-size-lg); + padding: 0; + border: none; + background: transparent; + color: var(--color-text-muted); + line-height: 1; +} +.header-icon-toggle[data-theme-state="light"] { + color: var(--color-text-strong); + } +.header-icon-toggle[data-theme-state="dark"] { + color: var(--color-text); + } +.header-icon-toggle__icon-wrapper { + display: inline-flex; + align-items: center; + justify-content: center; + inline-size: var(--space-lg); + block-size: var(--space-lg); +} +.header-icon-toggle__icon { + inline-size: 100%; + block-size: 100%; + display: none; + fill: currentColor; + } +.header-icon-toggle__icon-wrapper:not([data-theme-icon-state]), + .header-icon-toggle__icon-wrapper[data-theme-icon-state="light"] { + color: inherit; + } +.header-icon-toggle__icon-wrapper[data-theme-icon-state="light"] + .header-icon-toggle__icon--dark { + display: block; + } +.header-icon-toggle__icon-wrapper[data-theme-icon-state="dark"] + .header-icon-toggle__icon--light { + display: block; + } +.header-icon-toggle__icon-wrapper:not([data-theme-icon-state]) + .header-icon-toggle__icon--dark { + display: block; + } +#profileUnreadDot { + position: absolute; + top: var(--space-2xs); + right: var(--space-2xs); + width: var(--space-sm); + height: var(--space-sm); + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--color-page); + background-color: var(--status-danger); + display: none; + pointer-events: none; + } +#profileUnreadDot.is-visible { + display: block; + } +.header-icon-toggle[data-theme-state="light"]:hover, + .header-icon-toggle[data-theme-state="light"]:focus-visible { + color: var(--color-text); + } +.header-icon-toggle[data-theme-state="dark"]:hover, + .header-icon-toggle[data-theme-state="dark"]:focus-visible { + color: var(--color-text-strong); + } +.header-icon-toggle[aria-pressed="true"] { + color: var(--color-text-strong); + } +.header-icon-toggle[aria-pressed="true"]:hover, + .header-icon-toggle[aria-pressed="true"]:focus-visible { + color: var(--color-text-strong); + } + + .bv-modal.header-search__region { + display: none; + } +.profile-pane.header-search__region { + display: none; + } +.header-search__region { + display: none; + flex: 1 1 0%; + justify-content: center; +} +@media (min-width: 768px) { + .header-search__region { + display: flex; + } +} +.header-search__region { + min-width: 0; + padding-inline: clamp(var(--space-md), 4vw, var(--space-3xl)); + } +.header-search { + display: flex; + align-items: center; + gap: 0.75rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.4; + background-color: var(--surface-overlay-panel); + padding-left: 1rem; + padding-right: 1rem; + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + backdrop-filter: blur(var(--popover-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--popover-backdrop-blur)); + padding-block: calc(var(--space-sm) * 0.9); + inline-size: min(100%, var(--header-search-max-inline)); +} +.header-search:focus-within { + border-color: var(--color-accent-strong); +} +.header-search__icon { + display: block; + height: 1.25rem; + width: 1.25rem; + background-color: currentColor; + mask-repeat: no-repeat; + mask-position: center; + mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; + -webkit-mask-size: contain; +} +.header-search__icon--filter { + mask-image: url("../assets/svg/filter.svg"); + -webkit-mask-image: url("../assets/svg/filter.svg"); + } +.header-search__icon--submit { + mask-image: url("../assets/svg/search.svg"); + -webkit-mask-image: url("../assets/svg/search.svg"); + } +.header-search__filter { + outline: 2px solid transparent; + outline-offset: 2px; +} +.header-search__filter:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.header-search__filter { + display: inline-flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: transparent; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + color: var(--color-accent); + inline-size: calc(var(--icon-size-lg) * 0.9); + block-size: calc(var(--icon-size-lg) * 0.9); + min-inline-size: calc(var(--icon-size-lg) * 0.9); + min-block-size: calc(var(--icon-size-lg) * 0.9); +} +.header-search__filter:hover, + .header-search__filter:focus-visible { + color: var(--color-accent-strong); + } +.header-search__input { + flex: 1 1 0%; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + outline: 2px solid transparent; + outline-offset: 2px; +} +.header-search__input::-moz-placeholder { + color: var(--text-muted); +} +.header-search__input::placeholder { + color: var(--text-muted); +} +.header-search__input { + min-width: 0; + } +.header-search__input:focus-visible { + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.header-search__submit { + outline: 2px solid transparent; + outline-offset: 2px; +} +.header-search__submit:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.header-search__submit { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + background-color: var(--color-accent-strong); + color: var(--color-white); + inline-size: calc(var(--icon-size-lg) * 0.9); + block-size: calc(var(--icon-size-lg) * 0.9); + min-inline-size: calc(var(--icon-size-lg) * 0.9); + min-block-size: calc(var(--icon-size-lg) * 0.9); + padding: 0; +} +.header-search__submit:hover { + background-color: var(--color-accent); + } +.header-search__submit:focus-visible { + background-color: var(--color-accent-pressed); + } +.bv-logo { + --logo-wordmark-color: var(--color-logo-wordmark); + --logo-accent-color: var(--color-logo-accent); + --logo-background-color: var(--color-logo-background); + } +.bv-logo[data-variant="inverse"] { + --logo-wordmark-color: var(--color-logo-wordmark-inverse); + --logo-background-color: var(--color-logo-background-inverse); + } +.bv-logo[data-wordmark="current"] { + --logo-wordmark-color: currentColor; + } +.bv-logo[data-accent="current"] { + --logo-accent-color: currentColor; + } +.bv-logo[data-background="transparent"] { + --logo-background-color: transparent; + } +.bv-logo__wordmark { + fill: var(--logo-wordmark-color); + color: var(--logo-wordmark-color); + } +.bv-logo__accent { + fill: var(--logo-accent-color); + color: var(--logo-accent-color); + } +.bv-logo__background { + fill: var(--logo-background-color); + color: var(--logo-background-color); + } +.markdown-prose { + color: var(--color-text); + max-width: none; +} +.markdown-prose :where(p):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 1rem; +} +.markdown-prose :where([class~="lead"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-lead); + font-size: 1.25em; + line-height: 1.6; + margin-top: 1.2em; + margin-bottom: 1.2em; +} +.markdown-prose :where(a):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--color-primary); + text-decoration: none; + font-weight: 500; +} +.markdown-prose :where(strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-bold); + font-weight: 600; +} +.markdown-prose :where(a strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(blockquote strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(thead th strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(ol):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: decimal; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-inline-start: 1.625em; +} +.markdown-prose :where(ol[type="A"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-alpha; +} +.markdown-prose :where(ol[type="a"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-alpha; +} +.markdown-prose :where(ol[type="A" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-alpha; +} +.markdown-prose :where(ol[type="a" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-alpha; +} +.markdown-prose :where(ol[type="I"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-roman; +} +.markdown-prose :where(ol[type="i"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-roman; +} +.markdown-prose :where(ol[type="I" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: upper-roman; +} +.markdown-prose :where(ol[type="i" s]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: lower-roman; +} +.markdown-prose :where(ol[type="1"]):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: decimal; +} +.markdown-prose :where(ul):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + list-style-type: disc; + margin-top: 1.25em; + margin-bottom: 1.25em; + padding-inline-start: 1.625em; +} +.markdown-prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker { + font-weight: 400; + color: var(--tw-prose-counters); +} +.markdown-prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *))::marker { + color: var(--tw-prose-bullets); +} +.markdown-prose :where(dt):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + margin-top: 1.25em; +} +.markdown-prose :where(hr):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-color: var(--color-border-subtle); + border-top-width: 1px; + margin-top: 2rem; + margin-bottom: 2rem; +} +.markdown-prose :where(blockquote):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 500; + font-style: italic; + color: var(--color-muted); + border-inline-start-width: 0.25rem; + border-inline-start-color: var(--tw-prose-quote-borders); + quotes: "\201C""\201D""\2018""\2019"; + margin-top: 1rem; + margin-bottom: 1rem; + padding-inline-start: 1em; + border-left-width: 4px; + border-left-color: var(--color-border-subtle); + padding-left: 1rem; +} +.markdown-prose :where(blockquote p:first-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: open-quote; +} +.markdown-prose :where(blockquote p:last-of-type):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: close-quote; +} +.markdown-prose :where(h1):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 700; + font-size: var(--font-size-2xl); + margin-top: 0.5rem; + margin-bottom: 1rem; + line-height: 1.1111111; +} +.markdown-prose :where(h1 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 900; + color: inherit; +} +.markdown-prose :where(h2):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 700; + font-size: var(--font-size-xl); + margin-top: 1.25rem; + margin-bottom: 0.75rem; + line-height: 1.3333333; +} +.markdown-prose :where(h2 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 800; + color: inherit; +} +.markdown-prose :where(h3):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + font-size: var(--font-size-lg); + margin-top: 1rem; + margin-bottom: 0.75rem; + line-height: 1.6; +} +.markdown-prose :where(h3 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} +.markdown-prose :where(h4):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + margin-top: 1.5em; + margin-bottom: 0.5em; + line-height: 1.5; +} +.markdown-prose :where(h4 strong):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 700; + color: inherit; +} +.markdown-prose :where(img):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 1rem; + border-radius: var(--radius-md); + max-width: 100%; + height: auto; +} +.markdown-prose :where(picture):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + display: block; + margin-top: 2em; + margin-bottom: 2em; +} +.markdown-prose :where(video):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} +.markdown-prose :where(kbd):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 500; + font-family: inherit; + color: var(--tw-prose-kbd); + box-shadow: 0 0 0 1px var(--tw-prose-kbd-shadows), 0 3px 0 var(--tw-prose-kbd-shadows); + font-size: 0.875em; + border-radius: 0.3125rem; + padding-top: 0.1875em; + padding-inline-end: 0.375em; + padding-bottom: 0.1875em; + padding-inline-start: 0.375em; +} +.markdown-prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--color-secondary); + font-weight: 500; + font-size: var(--font-size-sm); + background-color: var(--color-page-alt); + padding: 0.2rem 0.4rem; + border-radius: var(--radius-md); + font-family: var(--font-family-mono); +} +.markdown-prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: none; +} +.markdown-prose :where(code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: none; +} +.markdown-prose :where(a code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(h1 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(h2 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; + font-size: 0.875em; +} +.markdown-prose :where(h3 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; + font-size: 0.9em; +} +.markdown-prose :where(h4 code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(blockquote code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(thead th code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: inherit; +} +.markdown-prose :where(pre):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--color-text-strong); + background-color: var(--color-page-alt); + overflow-x: auto; + font-weight: 400; + font-size: var(--font-size-sm); + line-height: 1.7142857; + margin-top: 0; + margin-bottom: 1rem; + border-radius: var(--radius-md); + padding-top: 0.8571429em; + padding-inline-end: 1.1428571em; + padding-bottom: 0.8571429em; + padding-inline-start: 1.1428571em; + padding: 1rem; + font-family: var(--font-family-mono); +} +.markdown-prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + background-color: transparent; + border-width: 0; + border-radius: 0; + padding: 0; + font-weight: inherit; + color: inherit; + font-size: inherit; + font-family: inherit; + line-height: inherit; +} +.markdown-prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::before { + content: none; +} +.markdown-prose :where(pre code):not(:where([class~="not-prose"],[class~="not-prose"] *))::after { + content: none; +} +.markdown-prose :where(table):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + width: 100%; + table-layout: auto; + margin-top: 2em; + margin-bottom: 2em; + font-size: 0.875em; + line-height: 1.7142857; +} +.markdown-prose :where(thead):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-th-borders); +} +.markdown-prose :where(thead th):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-headings); + font-weight: 600; + vertical-align: bottom; + padding-inline-end: 0.5714286em; + padding-bottom: 0.5714286em; + padding-inline-start: 0.5714286em; +} +.markdown-prose :where(tbody tr):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 1px; + border-bottom-color: var(--tw-prose-td-borders); +} +.markdown-prose :where(tbody tr:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-bottom-width: 0; +} +.markdown-prose :where(tbody td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + vertical-align: baseline; +} +.markdown-prose :where(tfoot):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + border-top-width: 1px; + border-top-color: var(--tw-prose-th-borders); +} +.markdown-prose :where(tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + vertical-align: top; +} +.markdown-prose :where(th, td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + text-align: start; +} +.markdown-prose :where(figure > *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 0; +} +.markdown-prose :where(figcaption):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + color: var(--tw-prose-captions); + font-size: 0.875em; + line-height: 1.4285714; + margin-top: 0.8571429em; +} +.markdown-prose { + --tw-prose-body: var(--color-text); + --tw-prose-headings: var(--color-text-strong); + --tw-prose-lead: #4b5563; + --tw-prose-links: var(--color-primary); + --tw-prose-bold: var(--color-text-strong); + --tw-prose-counters: var(--color-text-muted); + --tw-prose-bullets: var(--color-text-muted); + --tw-prose-hr: var(--color-border-subtle); + --tw-prose-quotes: var(--color-muted); + --tw-prose-quote-borders: #e5e7eb; + --tw-prose-captions: #6b7280; + --tw-prose-kbd: #111827; + --tw-prose-kbd-shadows: rgb(17 24 39 / 10%); + --tw-prose-code: var(--color-secondary); + --tw-prose-pre-code: #e5e7eb; + --tw-prose-pre-bg: #1f2937; + --tw-prose-th-borders: var(--color-border-subtle); + --tw-prose-td-borders: var(--color-border-subtle); + --tw-prose-invert-body: #d1d5db; + --tw-prose-invert-headings: #fff; + --tw-prose-invert-lead: #9ca3af; + --tw-prose-invert-links: #fff; + --tw-prose-invert-bold: #fff; + --tw-prose-invert-counters: #9ca3af; + --tw-prose-invert-bullets: #4b5563; + --tw-prose-invert-hr: #374151; + --tw-prose-invert-quotes: #f3f4f6; + --tw-prose-invert-quote-borders: #374151; + --tw-prose-invert-captions: #9ca3af; + --tw-prose-invert-kbd: #fff; + --tw-prose-invert-kbd-shadows: rgb(255 255 255 / 10%); + --tw-prose-invert-code: #fff; + --tw-prose-invert-pre-code: #d1d5db; + --tw-prose-invert-pre-bg: rgb(0 0 0 / 50%); + --tw-prose-invert-th-borders: #4b5563; + --tw-prose-invert-td-borders: #374151; + font-size: 1rem; + line-height: 1.6; +} +.markdown-prose :where(picture > img):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 0; +} +.markdown-prose :where(li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} +.markdown-prose :where(ol > li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0.375em; +} +.markdown-prose :where(ul > li):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0.375em; +} +.markdown-prose :where(.prose > ul > li p):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} +.markdown-prose :where(.prose > ul > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; +} +.markdown-prose :where(.prose > ul > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 1.25em; +} +.markdown-prose :where(.prose > ol > li > p:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; +} +.markdown-prose :where(.prose > ol > li > p:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 1.25em; +} +.markdown-prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.75em; + margin-bottom: 0.75em; +} +.markdown-prose :where(dl):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 1.25em; + margin-bottom: 1.25em; +} +.markdown-prose :where(dd):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0.5em; + padding-inline-start: 1.625em; +} +.markdown-prose :where(hr + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} +.markdown-prose :where(h2 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} +.markdown-prose :where(h3 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} +.markdown-prose :where(h4 + *):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} +.markdown-prose :where(thead th:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0; +} +.markdown-prose :where(thead th:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-end: 0; +} +.markdown-prose :where(tbody td, tfoot td):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-top: 0.5714286em; + padding-inline-end: 0.5714286em; + padding-bottom: 0.5714286em; + padding-inline-start: 0.5714286em; +} +.markdown-prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-start: 0; +} +.markdown-prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + padding-inline-end: 0; +} +.markdown-prose :where(figure):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 2em; + margin-bottom: 2em; +} +.markdown-prose :where(.prose > :first-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; +} +.markdown-prose :where(.prose > :last-child):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-bottom: 0; +} +.markdown-prose { + font-family: var(--font-family-sans); +} +.markdown-prose :where(h4, h5, h6):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + font-weight: 600; + margin-top: 0.75rem; + margin-bottom: 0.5rem; +} +.markdown-prose :where(ul, ol):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + margin-top: 0; + margin-bottom: 1rem; + padding-left: 1.25rem; +} +.markdown-prose :where(a:hover):not(:where([class~="not-prose"],[class~="not-prose"] *)) { + text-decoration: underline; +} +.markdown-prose { + max-width: none; + line-height: 1.625; + color: var(--text-primary); + --tw-prose-body: var(--color-text); + --tw-prose-headings: var(--color-text-strong); + --tw-prose-invert-headings: var(--color-text-strong); + --tw-prose-lead: var(--color-text); + --tw-prose-links: var(--color-accent-strong); + --tw-prose-bold: var(--color-text-strong); + --tw-prose-counters: var(--color-text-muted); + --tw-prose-bullets: var(--color-text-muted); + --tw-prose-hr: var(--color-border-translucent-strong); + --tw-prose-quotes: var(--color-text-strong); + --tw-prose-quote-borders: var(--color-border-subtle); + --tw-prose-captions: var(--color-text-muted); + --tw-prose-code: var(--color-text-strong); + --tw-prose-pre-code: var(--color-text); + --tw-prose-pre-bg: var(--surface-muted); + --tw-prose-th-borders: var(--color-border); + --tw-prose-td-borders: var(--color-border-subtle); +} +.markdown-prose :where(h1, h2, h3, h4, h5, h6) { + color: var(--color-text-strong); + } +.markdown-prose :where(h1, h2, h3, h4, h5, h6) strong { + color: inherit; + } +.markdown-prose a { + color: var(--color-accent-strong); + text-decoration-color: color-mix( + in srgb, + var(--color-accent-strong) 65%, + transparent + ); + text-decoration-thickness: var(--link-underline-thickness); + text-underline-offset: 0.2em; + } +.markdown-prose a:hover, + .markdown-prose a:focus-visible { + color: var(--color-accent); + text-decoration-line: underline; + } +.markdown-prose blockquote { + border-radius: var(--radius-md); + border-left-width: 4px; + border-color: var(--border-subtle); + background-color: var(--surface-muted); + --tw-bg-opacity: 0.5; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: var(--text-muted); +} +.markdown-prose :where(pre, code) { + font-family: var(--font-family-mono); +} +.markdown-prose code { + border-radius: var(--radius-md); + background-color: var(--surface-muted); + padding-left: 0.25rem; + padding-right: 0.25rem; + padding-top: 0.125rem; + padding-bottom: 0.125rem; + color: var(--color-accent-strong); +} +.markdown-prose pre { + overflow-x: auto; + border-radius: var(--radius-lg); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-muted); + padding: 1rem; + color: var(--text-primary); +} +.markdown-prose pre code { + background-color: transparent; + color: inherit; + padding: 0; + } +.\!popover { + position: relative; + display: inline-flex; +} +.popover { + position: relative; + display: inline-flex; +} +.popover-panel, + .popover__panel { + outline: 2px solid transparent; + outline-offset: 2px; +} +.popover-panel:focus-visible, + .popover__panel:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.popover-panel, + .popover__panel { + pointer-events: none; + z-index: var(--z-overlay-popover); + min-width: var(--menu-min-width); + max-width: var(--popover-inline-safe-max); + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + border-radius: var(--overlay-panel-radius); + border-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.4; + background-color: var(--surface-overlay-panel); + padding-left: var(--overlay-panel-padding-inline); + padding-right: var(--overlay-panel-padding-inline); + padding-top: var(--overlay-panel-padding-block); + padding-bottom: var(--overlay-panel-padding-block); + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + opacity: 0; + --tw-shadow: var(--overlay-panel-shadow); + --tw-shadow-colored: var(--overlay-panel-shadow); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-color: var(--surface-overlay-panel); + --tw-shadow: var(--tw-shadow-colored); + transition-property: opacity; + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + position: var(--popover-strategy, fixed); + left: var(--popover-left, 0); + top: var(--popover-top, 0); + max-width: var(--popover-max-width, none); + max-height: var(--popover-max-height, none); +} +.popover-panel[data-state="open"], + .popover__panel[data-state="open"] { + pointer-events: auto; + --tw-scale-x: 1; + --tw-scale-y: 1; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + opacity: 1; +} +.popover-panel[data-state="closed"], + .popover__panel[data-state="closed"] { + pointer-events: none; + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + opacity: 0; +} +.search-filter-chip { + display: inline-flex; + align-items: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 500; + color: var(--text-primary); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.search-filter-chip[data-state="on"] { + border-color: var(--color-accent-strong); + background-color: var(--color-accent-strong); + color: var(--color-white); +} +[data-popover-arrow="true"] { + left: var(--popover-arrow-left, auto); + right: var(--popover-arrow-right, auto); + top: var(--popover-arrow-top, auto); + bottom: var(--popover-arrow-bottom, auto); + } +.ds-overlay-backdrop { + position: fixed; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + background: var(--overlay-backdrop-color); + backdrop-filter: blur(var(--overlay-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--overlay-backdrop-blur)); + } +.popover-panel[data-variant="zap"], + .popover__panel[data-variant="zap"] { + background: var(--color-overlay-veil); + color: var(--color-subtle); + border: var(--border-width-hairline) solid + var(--color-border-translucent-stronger); + box-shadow: var(--shadow-popover-zap); + backdrop-filter: blur(var(--popover-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--popover-backdrop-blur)); + } +.\!btn { + outline: 2px solid transparent; + outline-offset: 2px; +} +.\!btn:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.\!btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: var(--color-accent-strong); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--color-white); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.btn { + outline: 2px solid transparent; + outline-offset: 2px; +} +.btn:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: var(--color-accent-strong); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--color-white); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!btn[data-size="sm"] { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); +} +.btn[data-size="sm"], + .btn-ghost[data-size="sm"] { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); +} +.\!btn[data-size="sm"] { + gap: 0.375rem; +} +.btn[data-size="sm"], + .btn-ghost[data-size="sm"] { + gap: 0.375rem; +} +.\!btn:hover { + background-color: var(--color-accent); +} +.btn:hover { + background-color: var(--color-accent); +} +.\!btn:focus-visible { + background-color: var(--color-accent-pressed); +} +.btn:focus-visible { + background-color: var(--color-accent-pressed); +} +.\!btn:disabled { + pointer-events: none; + cursor: not-allowed; + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.btn:disabled { + pointer-events: none; + cursor: not-allowed; + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.btn-link { + outline: 2px solid transparent; + outline-offset: 2px; +} +.btn-link:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.btn-link { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + color: var(--color-accent); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.btn-link:hover, + .btn-link:focus-visible { + color: var(--color-accent-strong); + text-decoration-line: underline; +} +.progress, + [data-progress-meter] { + --progress-height: var(--progress-height-md); + --progress-track: var(--progress-track-color); + --progress-fill: var(--progress-fill-color); + --progress-radius-current: var(--progress-radius); + display: block; + width: 100%; + height: var(--progress-height); + border: none; + border-radius: var(--progress-radius-current); + overflow: hidden; + background-color: var(--progress-track); + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + } +.progress::-webkit-progress-bar, + [data-progress-meter]::-webkit-progress-bar { + background-color: var(--progress-track); + border-radius: var(--progress-radius-current); + } +.progress::-webkit-progress-value, + [data-progress-meter]::-webkit-progress-value { + background-color: var(--progress-fill); + border-radius: var(--progress-radius-current); + -webkit-transition: width var(--progress-transition-duration) + var(--progress-transition-ease); + transition: width var(--progress-transition-duration) + var(--progress-transition-ease); + } +.progress::-moz-progress-bar, + [data-progress-meter]::-moz-progress-bar { + background-color: var(--progress-fill); + border-radius: var(--progress-radius-current); + -moz-transition: width var(--progress-transition-duration) + var(--progress-transition-ease); + transition: width var(--progress-transition-duration) + var(--progress-transition-ease); + } +.progress[data-variant="surface"], + [data-progress-meter][data-variant="surface"], + .progress.progress--surface, + [data-progress-meter].progress--surface { + --progress-track: var(--color-panel); + } +.progress[data-variant="accent"], + [data-progress-meter][data-variant="accent"], + .progress.progress--accent, + [data-progress-meter].progress--accent { + --progress-fill: var(--color-info-strong); + } +.btn-ghost { + outline: 2px solid transparent; + outline-offset: 2px; +} +.btn-ghost:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.btn-ghost { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: var(--color-accent-strong); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--color-white); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.btn-ghost[data-size="sm"] { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + gap: 0.375rem; +} +.btn-ghost:hover { + background-color: var(--color-accent); +} +.btn-ghost:focus-visible { + background-color: var(--color-accent-pressed); +} +.btn-ghost:disabled { + pointer-events: none; + cursor: not-allowed; + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +body.iframe-form button.btn-ghost { + align-self: flex-start; + margin-top: var(--space-md); + } +.btn-ghost { + border-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.6; + background-color: transparent; + color: var(--text-primary); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +@media (prefers-reduced-motion: reduce) { + + .btn-ghost { + transition-property: none; + } +} +.btn-ghost:hover { + background-color: var(--surface-panel-hover); + color: var(--text-primary); +} +.btn-ghost:focus-visible { + background-color: var(--surface-panel-hover); +} +.btn-ghost:disabled { + pointer-events: none; + opacity: 0.5; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.btn-ghost[data-variant="critical"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.6; + color: var(--color-critical); +} +.btn-ghost[data-variant="critical"]:hover, + .btn-ghost[data-variant="critical"]:focus-visible { + background-color: var(--color-critical); + --tw-bg-opacity: 0.2; + color: var(--color-critical-strong); +} +.login-option { + outline: 2px solid transparent; + outline-offset: 2px; +} +.login-option:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.login-option { + position: relative; + display: flex; + height: 100%; + width: 100%; + flex-direction: column; + gap: 1rem; + overflow: hidden; + border-width: 1px; + border-color: var(--border-default); + background-color: var(--surface-overlay-panel-soft); + padding-left: 1.5rem; + padding-right: 1.5rem; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + text-align: left; + color: var(--text-primary); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 300ms; + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + border-radius: calc(var(--radius-xl) * 1.12); + isolation: isolate; + backdrop-filter: blur(var(--blur-modal-backdrop)); + background-image: linear-gradient( + 140deg, + color-mix(in srgb, var(--surface-overlay-panel-soft) 88%, transparent) 0%, + color-mix(in srgb, var(--surface-overlay-panel) 72%, transparent) 100% + ); + transform: translate3d(0, 0, 0); + transition-property: border-color, box-shadow, transform; +} +.login-option::after { + content: ""; + position: absolute; + inset: 0; + z-index: 0; + border-radius: inherit; + opacity: 0; + transform: translate3d(0, 14%, 0); + transition: + opacity 220ms ease, + transform 220ms ease; + background: radial-gradient( + 115% 115% at 0% 0%, + color-mix(in srgb, var(--status-neutral) 32%, transparent) 0%, + transparent 65% + ); + } +.login-option:hover, + .login-option:focus-visible { + border-color: var(--border-strong); + box-shadow: var(--shadow-modal); + transform: translate3d(0, var(--motion-login-option-hover-translate), 0); +} +.login-option:hover::after, + .login-option:focus-visible::after { + opacity: 0.65; + transform: translate3d(0, 0, 0); + } +.login-option:disabled, + .login-option[aria-disabled="true"] { + cursor: not-allowed; + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transform: none; +} +.login-option[data-tone="accent"]::after { + background: radial-gradient( + 120% 120% at 0% 0%, + color-mix(in srgb, var(--status-info) 38%, transparent) 0%, + transparent 65% + ); + } +.login-option[data-tone="warning"]::after { + background: radial-gradient( + 120% 120% at 0% 0%, + color-mix(in srgb, var(--status-warning) 42%, transparent) 0%, + transparent 65% + ); + } +.login-option--primary { + border-color: var(--border-default); +} +.login-option--ghost { + background-image: linear-gradient( + 145deg, + color-mix(in srgb, var(--surface-overlay-panel-soft) 82%, transparent) 0%, + color-mix(in srgb, var(--surface-overlay-panel-soft) 68%, transparent) + 100% + ); + } +.login-option--outline { + border-color: var(--border-strong); +} +.login-option--link { + border-width: 1px; + border-color: transparent; + background-color: transparent; + color: var(--color-accent); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.login-option__header, + .login-option__copy, + .login-option__status, + .login-option__capabilities { + position: relative; + z-index: 1; + } +.login-option__header { + display: flex; + width: 100%; + align-items: flex-start; + justify-content: space-between; + gap: 1rem; +} +.login-option__copy { + display: flex; + min-width: 0px; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; +} +.login-option__eyebrow { + font-size: var(--font-size-2xs); + font-weight: 600; + text-transform: uppercase; + color: var(--text-muted); + letter-spacing: 0.18em; +} +.login-option:hover .login-option__eyebrow, + .login-option:focus-visible .login-option__eyebrow { + color: var(--text-primary); +} +.login-option__label { + font-size: var(--font-size-lg); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--text-primary); +} +.login-option__description { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + line-height: 1.625; + color: var(--text-muted); +} +.login-option__chevron { + display: inline-flex; + height: 2.25rem; + width: 2.25rem; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + background-color: var(--surface-overlay-panel); + color: var(--text-muted); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 200ms; + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + box-shadow: inset 0 0 0 var(--border-width-hairline) + color-mix(in srgb, var(--border-overlay) 60%, transparent); +} +.login-option:hover .login-option__chevron, + .login-option:focus-visible .login-option__chevron { + background-color: var(--color-accent); + color: var(--color-white); + box-shadow: none; +} +.login-option__status { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-muted); +} +.login-option__capabilities { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + position: relative; +} +.btn-ghost[data-state="active"], + .btn-ghost[aria-pressed="true"] { + border-color: transparent; + background-color: var(--color-primary); + color: var(--color-white); + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.btn-ghost[data-state="active"]:hover, + .btn-ghost[data-state="active"]:focus-visible, + .btn-ghost[aria-pressed="true"]:hover, + .btn-ghost[aria-pressed="true"]:focus-visible { + background-color: var(--color-accent-strong); +} +/* + * Blog embed heights are now driven by the iframe content via postMessage. + * Styling lives inline so the shell can expand naturally with its card. + */ +/* + * Blog carousel component styles + * Tokens consumed here are defined in css/tokens.css under the + * "Blog carousel tokens" section: + */ +.\!badge { + display: inline-flex; + align-items: center; + gap: 0.25rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: uppercase; + letter-spacing: var(--tracking-extra-wide); + color: var(--status-neutral-on); +} +.badge { + display: inline-flex; + align-items: center; + gap: 0.25rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: uppercase; + letter-spacing: var(--tracking-extra-wide); + color: var(--status-neutral-on); +} +.\!badge[data-variant="info"] { + border-color: var(--status-info-border); + background-color: var(--status-info-surface); + color: var(--status-info-on); +} +.badge[data-variant="info"] { + border-color: var(--status-info-border); + background-color: var(--status-info-surface); + color: var(--status-info-on); +} +.\!badge[data-variant="success"] { + border-color: var(--status-success-border); + background-color: var(--status-success-surface); + color: var(--status-success-on); +} +.badge[data-variant="success"] { + border-color: var(--status-success-border); + background-color: var(--status-success-surface); + color: var(--status-success-on); +} +.\!badge[data-variant="warning"] { + border-color: var(--status-warning-border); + background-color: var(--status-warning-surface); + color: var(--status-warning-on); +} +.badge[data-variant="warning"] { + border-color: var(--status-warning-border); + background-color: var(--status-warning-surface); + color: var(--status-warning-on); +} +.\!badge[data-variant="critical"] { + border-color: var(--status-danger-border); + background-color: var(--status-danger-surface); + color: var(--status-danger-on); +} +.badge[data-variant="critical"] { + border-color: var(--status-danger-border); + background-color: var(--status-danger-surface); + color: var(--status-danger-on); +} +.\!badge[data-variant="private"] { + border-color: var(--status-private-border); + background-color: var(--status-private-surface); + color: var(--status-private-on); +} +.badge[data-variant="private"] { + border-color: var(--status-private-border); + background-color: var(--status-private-surface); + color: var(--status-private-on); +} +.\!badge[data-variant="neutral"] { + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + color: var(--status-neutral-on); +} +.badge[data-variant="neutral"] { + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + color: var(--status-neutral-on); +} +.moderation-badge { + display: inline-flex; + flex-direction: column; + align-items: flex-start; + gap: var(--space-sm); + border-radius: var(--radius-xl); + border-width: 1px; + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: none; + letter-spacing: -0.025em; + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.moderation-badge--interactive { + pointer-events: auto; + } +.moderation-badge__actions { + display: inline-flex; + flex-wrap: nowrap; + align-items: center; + gap: var(--space-sm); +} +.moderation-badge__label { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + white-space: nowrap; +} +.moderation-badge[data-variant="warning"] { + border-color: var(--status-warning-border); + background-color: var(--status-warning-surface); + color: var(--status-warning-on); + box-shadow: 0 var(--shadow-badge-offset-y) var(--shadow-badge-blur) + color-mix(in srgb, var(--status-warning) 18%, transparent); +} +.moderation-badge[data-variant="neutral"] { + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + color: var(--status-neutral-on); + box-shadow: 0 var(--shadow-badge-offset-y) var(--shadow-badge-blur) + color-mix(in srgb, var(--status-neutral) 18%, transparent); +} +.moderation-badge__icon { + display: inline-flex; + height: 1.25rem; + width: 1.25rem; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + background-color: var(--status-warning-surface); + background-color: color-mix( + in srgb, + var(--status-warning) 18%, + transparent + ); + color: var(--status-warning-on); +} +.moderation-badge[data-variant="neutral"] .moderation-badge__icon { + background-color: var(--status-neutral-surface); + background-color: color-mix( + in srgb, + var(--status-neutral) 18%, + transparent + ); + color: var(--status-neutral-on); +} +.moderation-badge__icon-mark { + height: 0.875rem; + width: 0.875rem; +} +.moderation-badge__text { + white-space: nowrap; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + letter-spacing: -0.025em; +} +.moderation-badge__action { + display: inline-flex; + align-items: center; + gap: 0.375rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--status-warning-border); + background-color: var(--status-warning-surface); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: none; + letter-spacing: -0.025em; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + background-color: color-mix( + in srgb, + var(--status-warning) 16%, + transparent + ); + border-color: color-mix( + in srgb, + var(--status-warning-border) 80%, + transparent + ); + color: var(--status-warning-on); +} +.moderation-badge[data-variant="warning"] .moderation-badge__action:hover { + background-color: color-mix( + in srgb, + var(--status-warning) 24%, + transparent + ); + } +.moderation-badge[data-variant="neutral"] .moderation-badge__action { + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + background-color: color-mix( + in srgb, + var(--status-neutral) 16%, + transparent + ); + border-color: color-mix( + in srgb, + var(--status-neutral-border) 80%, + transparent + ); + color: var(--status-neutral-on); +} +.moderation-badge[data-variant="neutral"] .moderation-badge__action:hover { + background-color: color-mix( + in srgb, + var(--status-neutral) 24%, + transparent + ); + } +.moderation-badge__action:focus-visible { + outline: var(--outline-thick-width) solid + color-mix(in srgb, var(--status-warning) 38%, transparent); + outline-offset: var(--space-3xs); + } +.moderation-badge[data-variant="neutral"] + .moderation-badge__action:focus-visible { + outline: var(--outline-thick-width) solid + color-mix(in srgb, var(--status-neutral) 38%, transparent); + } +.moderation-badge__action[disabled] { + cursor: wait; + opacity: 0.7; + } +.pill { + display: inline-flex; + align-items: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 500; + color: var(--status-neutral-on); +} +.pill[data-size="compact"] { + padding-left: 0.5rem; + padding-right: 0.5rem; + padding-top: 0.125rem; + padding-bottom: 0.125rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); +} +.pill[data-variant="info"] { + border-color: var(--status-info-border); + background-color: var(--status-info-surface); + color: var(--status-info-on); +} +.pill[data-variant="success"] { + border-color: var(--status-success-border); + background-color: var(--status-success-surface); + color: var(--status-success-on); +} +.pill[data-variant="warning"] { + border-color: var(--status-warning-border); + background-color: var(--status-warning-surface); + color: var(--status-warning-on); +} +.pill[data-variant="critical"] { + border-color: var(--status-danger-border); + background-color: var(--status-danger-surface); + color: var(--status-danger-on); +} +.pill[data-variant="private"] { + border-color: var(--status-private-border); + background-color: var(--status-private-surface); + color: var(--status-private-on); +} +.pill[data-variant="neutral"] { + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + color: var(--status-neutral-on); +} +.\!menu { + display: flex; + flex-direction: column; + gap: 0.25rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.menu { + display: flex; + flex-direction: column; + gap: 0.25rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.menu__heading { + padding-left: 1rem; + padding-right: 1rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.025em; + color: var(--text-muted); +} +.menu__separator { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + height: 1px; + background-color: var(--border-default); + --tw-bg-opacity: 0.2; +} +.menu__item { + outline: 2px solid transparent; + outline-offset: 2px; +} +.menu__item:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.menu__item { + position: relative; + display: flex; + width: 100%; + align-items: center; + gap: 0.75rem; + border-radius: var(--radius-md); + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 500; + color: var(--text-primary); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: var(--motion-ease-in-out); +} +.menu__item:hover { + background-color: var(--surface-panel-hover); + color: var(--text-primary); +} +.menu__item[data-state="active"] { + background-color: var(--color-accent); + --tw-bg-opacity: 0.2; + color: var(--color-accent-strong); +} +.menu__item[data-variant="critical"] { + color: var(--color-critical-strong); +} +.menu__item[data-variant="critical"]:hover { + background-color: var(--color-critical); + --tw-bg-opacity: 0.2; +} +.menu__item:disabled, + .menu__item[aria-disabled="true"] { + cursor: not-allowed; + background-color: transparent; + color: var(--text-muted); + opacity: 0.6; +} +.menu__item:disabled:hover, + .menu__item[aria-disabled="true"]:hover { + background-color: transparent; + color: var(--text-muted); +} +.\!card { + min-width: 0 !important; + --video-card-lift-translate-y: 0 !important; + --video-card-backdrop-opacity: 0 !important; + --video-card-backdrop-translate-y: var(--space-md-plus) !important; + --video-card-backdrop-scale: 1.08 !important; + --video-card-backdrop-blur: var(--blur-thumbnail-blur) !important; + } +.card { + min-width: 0; + --video-card-lift-translate-y: 0; + --video-card-backdrop-opacity: 0; + --video-card-backdrop-translate-y: var(--space-md-plus); + --video-card-backdrop-scale: 1.08; + --video-card-backdrop-blur: var(--blur-thumbnail-blur); + } +.\!card { + outline: 2px solid transparent; + outline-offset: 2px; +} +.\!card:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.\!card { + position: relative; + border-radius: var(--radius-lg); + border-width: 1px; + border-color: transparent; + background-color: var(--surface-raised); + color: var(--text-primary); + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.card { + outline: 2px solid transparent; + outline-offset: 2px; +} +.card:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.card { + position: relative; + border-radius: var(--radius-lg); + border-width: 1px; + border-color: transparent; + background-color: var(--surface-raised); + color: var(--text-primary); + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!card { + transform: translate3d(0, var(--video-card-lift-translate-y), 0) !important; + transition-property: + transform, box-shadow, border-color, background-color, color !important; + will-change: transform !important; + isolation: isolate !important; + } +.card { + transform: translate3d(0, var(--video-card-lift-translate-y), 0); + transition-property: + transform, box-shadow, border-color, background-color, color; + will-change: transform; + isolation: isolate; + } +.\!card::before { + content: "" !important; + position: absolute !important; + inset: 0 !important; + z-index: 0 !important; + opacity: var(--video-card-backdrop-opacity) !important; + background-image: var(--video-card-thumb-url, none) !important; + background-position: center !important; + background-repeat: no-repeat !important; + background-size: cover !important; + transform: translate3d(0, var(--video-card-backdrop-translate-y), 0) + scale(var(--video-card-backdrop-scale)) !important; + filter: blur(var(--video-card-backdrop-blur)) !important; + transition: + opacity var(--motion-duration-base) var(--motion-ease-in-out), + transform var(--motion-duration-base) var(--motion-ease-in-out), + filter var(--motion-duration-base) var(--motion-ease-in-out) !important; + pointer-events: none !important; + will-change: opacity, transform, filter !important; + } +.card::before { + content: ""; + position: absolute; + inset: 0; + z-index: 0; + opacity: var(--video-card-backdrop-opacity); + background-image: var(--video-card-thumb-url, none); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + transform: translate3d(0, var(--video-card-backdrop-translate-y), 0) + scale(var(--video-card-backdrop-scale)); + filter: blur(var(--video-card-backdrop-blur)); + transition: + opacity var(--motion-duration-base) var(--motion-ease-in-out), + transform var(--motion-duration-base) var(--motion-ease-in-out), + filter var(--motion-duration-base) var(--motion-ease-in-out); + pointer-events: none; + will-change: opacity, transform, filter; + } +.\!card > * { + position: relative !important; + z-index: 1 !important; + } +.card > * { + position: relative; + z-index: 1; + } +.card--compact { + display: flex; + flex-direction: row; + align-items: flex-start; + gap: var(--space-md); +} +.card--compact .video-card__media { + inline-size: clamp( + var(--video-card-compact-media-min), + calc(var(--video-modal-secondary-min) * 0.4), + var(--video-card-compact-media-max) + ); + flex-basis: clamp( + var(--video-card-compact-media-min), + calc(var(--video-modal-secondary-min) * 0.4), + var(--video-card-compact-media-max) + ); + display: block; + flex-shrink: 0; + overflow: hidden; + border-radius: var(--radius-lg); + } +.card--compact .video-card__content { + display: flex; + min-width: 0px; + flex: 1 1 0%; + flex-direction: column; + gap: var(--space-sm); + padding: var(--space-md); +} +.card--compact .video-card__title { + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + line-height: 1.375; +} +.card--compact .video-card__author-name { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); +} +.card--compact .video-card__meta { + margin-top: 0px; + display: flex; + align-items: center; + gap: 0.5rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + color: var(--text-muted-strong); +} +.card--compact .video-card__meta .view-count-text { + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); +} +.\!card:hover, + .\!card:focus-within { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + } +.card:hover, + .card:focus-within { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + } +.\!card:hover, + .\!card:focus-within { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } +.card:hover, + .card:focus-within { + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.\!card:hover, + .\!card:focus-within { + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.\!card:focus-visible { + border-color: var(--color-accent); + --tw-border-opacity: 0.4; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.card:focus-visible { + border-color: var(--color-accent); + --tw-border-opacity: 0.4; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.\!card[data-state="critical"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +.card[data-state="critical"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +.\!card[data-state="private"] { + background-color: var(--surface-raised-private); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.card[data-state="private"] { + background-color: var(--surface-raised-private); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.\!card[data-state="disabled"] { + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.card[data-state="disabled"] { + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.video-card__title { + transition: color var(--motion-duration-base) var(--motion-ease-in-out); + } +.video-card__title:hover, + .video-card__title:focus-visible { + color: var(--color-accent); + } +.form-control { + outline: 2px solid transparent; + outline-offset: 2px; +} +.form-control:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.form-control { + display: block; + width: 100%; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.form-control::-moz-placeholder { + color: var(--text-muted); +} +.form-control::placeholder { + color: var(--text-muted); +} +.form-control:hover { + border-color: var(--border-default); +} +.form-control:focus-visible { + border-color: var(--color-accent-strong); +} +.form-control:disabled { + cursor: not-allowed; + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.form-control:invalid { + border-color: var(--color-critical); + --tw-border-opacity: 0.6; +} +.form-control[data-state="locked"], + .input[data-state="locked"], + .textarea[data-state="locked"], + .select[data-state="locked"], + textarea.form-control[data-state="locked"], + select.form-control[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} + + .\!input[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} +.form-control[data-state="locked"]:focus-visible, + .input[data-state="locked"]:focus-visible, + .textarea[data-state="locked"]:focus-visible, + .select[data-state="locked"]:focus-visible, + textarea.form-control[data-state="locked"]:focus-visible, + select.form-control[data-state="locked"]:focus-visible { + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} + + .\!input[data-state="locked"]:focus-visible { + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} +.form-control[data-state="locked"]:disabled, + .input[data-state="locked"]:disabled, + .textarea[data-state="locked"]:disabled, + .select[data-state="locked"]:disabled, + textarea.form-control[data-state="locked"]:disabled, + select.form-control[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} + + .\!input[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} +.\!input { + outline: 2px solid transparent; + outline-offset: 2px; +} +.\!input:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.\!input { + display: block; + width: 100%; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!input::-moz-placeholder { + color: var(--text-muted); +} +.\!input::placeholder { + color: var(--text-muted); +} +.\!input:hover { + border-color: var(--border-default); +} +.\!input:focus-visible { + border-color: var(--color-accent-strong); +} +.\!input:disabled { + cursor: not-allowed; + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.\!input:invalid { + border-color: var(--color-critical); + --tw-border-opacity: 0.6; +} +.\!input[data-state="locked"], + textarea.\!input[data-state="locked"], + select.\!input[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} +.\!input[data-state="locked"]:focus-visible, + textarea.\!input[data-state="locked"]:focus-visible, + select.\!input[data-state="locked"]:focus-visible { + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} +.\!input[data-state="locked"]:disabled, + textarea.\!input[data-state="locked"]:disabled, + select.\!input[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} +@media (prefers-reduced-motion: reduce) { + .\!input { + transition: none; + } + } +body.iframe-form label + .\!input { + margin-top: var(--space-xs); + } +.input { + outline: 2px solid transparent; + outline-offset: 2px; +} +.input:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.input { + display: block; + width: 100%; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.input::-moz-placeholder { + color: var(--text-muted); +} +.input::placeholder { + color: var(--text-muted); +} +.input:hover { + border-color: var(--border-default); +} +.input:focus-visible { + border-color: var(--color-accent-strong); +} +.input:disabled { + cursor: not-allowed; + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.input:invalid { + border-color: var(--color-critical); + --tw-border-opacity: 0.6; +} +.input[data-state="locked"], + textarea.input[data-state="locked"], + select.input[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} +.input[data-state="locked"]:focus-visible, + textarea.input[data-state="locked"]:focus-visible, + select.input[data-state="locked"]:focus-visible { + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} +.input[data-state="locked"]:disabled, + textarea.input[data-state="locked"]:disabled, + select.input[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} +@media (prefers-reduced-motion: reduce) { + .input { + transition: none; + } + } +body.iframe-form label + .input { + margin-top: var(--space-xs); + } +.textarea { + outline: 2px solid transparent; + outline-offset: 2px; +} +.textarea:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.textarea { + display: block; + width: 100%; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.textarea::-moz-placeholder { + color: var(--text-muted); +} +.textarea::placeholder { + color: var(--text-muted); +} +.textarea:hover { + border-color: var(--border-default); +} +.textarea:focus-visible { + border-color: var(--color-accent-strong); +} +.textarea:disabled { + cursor: not-allowed; + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.textarea:invalid { + border-color: var(--color-critical); + --tw-border-opacity: 0.6; +} +.textarea[data-state="locked"], + textarea.textarea[data-state="locked"], + select.textarea[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} +.textarea[data-state="locked"]:focus-visible, + textarea.textarea[data-state="locked"]:focus-visible, + select.textarea[data-state="locked"]:focus-visible { + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} +.textarea[data-state="locked"]:disabled, + textarea.textarea[data-state="locked"]:disabled, + select.textarea[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} +@media (prefers-reduced-motion: reduce) { + .textarea { + transition: none; + } + } +body.iframe-form label + .textarea { + margin-top: var(--space-xs); + } +.textarea { + min-height: var(--form-textarea-min-height); + resize: vertical; +} +.select { + outline: 2px solid transparent; + outline-offset: 2px; +} +.select:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.select { + display: block; + width: 100%; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.select::-moz-placeholder { + color: var(--text-muted); +} +.select::placeholder { + color: var(--text-muted); +} +.select:hover { + border-color: var(--border-default); +} +.select:focus-visible { + border-color: var(--color-accent-strong); +} +.select:disabled { + cursor: not-allowed; + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.select:invalid { + border-color: var(--color-critical); + --tw-border-opacity: 0.6; +} +.select[data-state="locked"], + textarea.select[data-state="locked"], + select.select[data-state="locked"] { + cursor: default; + border-color: var(--border-sidebar-strong); + background-color: var(--surface-overlay-panel-soft); + color: var(--text-muted); +} +.select[data-state="locked"]:focus-visible, + textarea.select[data-state="locked"]:focus-visible, + select.select[data-state="locked"]:focus-visible { + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + border-color: var(--border-sidebar-strong); + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + outline: 2px solid transparent; + outline-offset: 2px; + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-offset-width: 0px; +} +.select[data-state="locked"]:disabled, + textarea.select[data-state="locked"]:disabled, + select.select[data-state="locked"]:disabled { + cursor: default; + opacity: 1; +} +@media (prefers-reduced-motion: reduce) { + .select { + transition: none; + } + } +body.iframe-form label + .select { + margin-top: var(--space-xs); + } +.select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding-right: 2.5rem; + --select-arrow-color: var(--color-border); + background-image: + linear-gradient(135deg, transparent 50%, var(--select-arrow-color) 50%), + linear-gradient(45deg, var(--select-arrow-color) 50%, transparent 50%), + linear-gradient( + to right, + var(--color-border-subtle), + var(--color-border-subtle) + ); + background-position: + right var(--form-select-icon-offset) center, + right var(--form-select-icon-gap) center, + right var(--form-select-icon-hit-area) center; + background-size: + var(--form-select-icon-size) var(--form-select-icon-size), + var(--form-select-icon-size) var(--form-select-icon-size), + var(--form-select-divider-width) 60%; + background-repeat: no-repeat; +} +.select:hover { + --select-arrow-color: var(--color-border); + } +.select:focus-visible { + --select-arrow-color: var(--color-accent-strong); + } +.select:disabled { + --select-arrow-color: var(--color-border-subtle); + } +.select:invalid { + --select-arrow-color: var(--color-critical); + } +.\!checkbox { + outline: 2px solid transparent; + outline-offset: 2px; +} +.\!checkbox:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.\!checkbox { + display: inline-flex; + height: 1.25rem; + width: 1.25rem; + cursor: pointer; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + align-items: center; + justify-content: center; + border-radius: 0.25rem; + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + color: var(--color-white); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.checkbox { + outline: 2px solid transparent; + outline-offset: 2px; +} +.checkbox:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.checkbox { + display: inline-flex; + height: 1.25rem; + width: 1.25rem; + cursor: pointer; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + align-items: center; + justify-content: center; + border-radius: 0.25rem; + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-alt); + color: var(--color-white); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!checkbox:hover { + border-color: var(--border-default); +} +.checkbox:hover { + border-color: var(--border-default); +} +.\!checkbox:disabled { + cursor: not-allowed; + border-color: var(--border-subtle); + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.checkbox:disabled { + cursor: not-allowed; + border-color: var(--border-subtle); + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.\!checkbox::after { + content: "" !important; + } +.checkbox::after { + content: ""; + } +.\!checkbox::after { + pointer-events: none; + height: 0.5rem; + width: 0.75rem; + border-bottom-width: 2px; + border-right-width: 2px; + border-color: var(--color-white); + opacity: 0; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.checkbox::after { + pointer-events: none; + height: 0.5rem; + width: 0.75rem; + border-bottom-width: 2px; + border-right-width: 2px; + border-color: var(--color-white); + opacity: 0; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!checkbox::after { + transform: rotate(45deg) translateY(var(--form-checkbox-checkmark-offset)) + scale(0.85) !important; + } +.checkbox::after { + transform: rotate(45deg) translateY(var(--form-checkbox-checkmark-offset)) + scale(0.85); + } +.\!checkbox:checked, + .\!checkbox[aria-checked="true"] { + border-color: var(--color-accent-strong); + background-color: var(--color-accent-strong); +} +.checkbox:checked, + .checkbox[aria-checked="true"] { + border-color: var(--color-accent-strong); + background-color: var(--color-accent-strong); +} +.\!checkbox:checked, + .\!checkbox[aria-checked="true"] { + border-color: var(--color-accent-strong); + background-color: var(--color-accent-strong); +} +.\!checkbox:checked::after, + .\!checkbox[aria-checked="true"]::after { + opacity: 1; +} +.checkbox:checked::after, + .checkbox[aria-checked="true"]::after { + opacity: 1; +} +.\!checkbox:checked::after, + .\!checkbox[aria-checked="true"]::after { + opacity: 1; + transform: rotate(45deg) translateY(var(--form-checkbox-checkmark-offset)) + scale(1) !important; +} +.checkbox:checked::after, + .checkbox[aria-checked="true"]::after { + transform: rotate(45deg) translateY(var(--form-checkbox-checkmark-offset)) + scale(1); + } +.\!checkbox:checked::after, + .\!checkbox[aria-checked="true"]::after { + transform: rotate(45deg) translateY(var(--form-checkbox-checkmark-offset)) + scale(1) !important; + } +.switch { + outline: 2px solid transparent; + outline-offset: 2px; +} +.switch:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.switch { + position: relative; + display: inline-flex; + height: 1.5rem; + width: 2.75rem; + cursor: pointer; + align-items: center; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--border-subtle); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.switch::before { + content: ""; + pointer-events: none; + position: absolute; + left: 0.125rem; + top: 50%; + height: 1.25rem; + width: 1.25rem; + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + border-radius: var(--radius-full); + background-color: var(--surface-base); + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + } +.switch:disabled { + cursor: not-allowed; + border-color: var(--border-subtle); + background-color: var(--surface-base); + color: var(--text-muted); + opacity: 0.6; +} +.switch[aria-checked="true"], + .switch.is-on { + border-color: var(--color-accent-strong); + background-color: var(--color-accent-strong); +} +.switch[aria-checked="true"]::before, + .switch.is-on::before { + --tw-translate-x: 1.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +@media (prefers-reduced-motion: reduce) { + .form-control, + .checkbox, + .checkbox::after, + .switch, + .switch::before, + .popover-panel, + .popover__panel, + .menu__item { + transition: none !important; + } + + .\!checkbox, + .\!checkbox::after { + transition: none !important; + } + } +.bv-modal { + position: fixed; + inset: 0px; + z-index: var(--z-modal-root); + display: flex; + align-items: center; + justify-content: center; + padding: 1.5rem; +} +@media (min-width: 640px) { + .bv-modal { + padding: 2rem; + } +} +.bv-modal[hidden], + .bv-modal.hidden { + display: none !important; + } +.bv-modal__panel { + outline: 2px solid transparent; + outline-offset: 2px; +} +.bv-modal__panel:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.bv-modal__panel { + position: relative; + z-index: var(--z-modal-content); + width: 100%; + max-width: var(--modal-max-width); + border-radius: var(--radius-modal-xl); + border-width: 1px; + border-color: var(--border-overlay); + padding-left: 2rem; + padding-right: 2rem; + padding-bottom: 2rem; + padding-top: 1.75rem; + text-align: left; + color: var(--text-primary); + --tw-shadow: var(--shadow-modal); + --tw-shadow-colored: var(--shadow-modal); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + background-color: var(--color-modal-surface, var(--color-overlay-panel)); +} +.bv-modal__panel:focus-visible { + border-color: var(--color-border-translucent-bright); +} +.bv-modal-backdrop { + position: fixed; + inset: 0px; + z-index: var(--z-modal-overlay); + --tw-backdrop-saturate: saturate(1.5); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + background-color: var(--color-modal-backdrop, var(--color-overlay-muted)); + backdrop-filter: blur(var(--blur-modal-backdrop)); + -webkit-backdrop-filter: blur(var(--blur-modal-backdrop)); +} +.bv-modal-backdrop[data-variant="veil"] { + --tw-backdrop-blur: blur(64px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + background-color: var(--color-overlay-veil); +} +.bv-modal-backdrop[data-variant="muted"] { + background-color: var(--color-overlay-muted); + } +.modal-sheet { + outline: 2px solid transparent; + outline-offset: 2px; +} +.modal-sheet:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.modal-sheet { + position: relative; + z-index: var(--z-modal-content); + width: 100%; + max-width: var(--modal-max-width); + border-radius: var(--radius-modal-xl); + border-width: 1px; + border-color: var(--border-overlay); + padding-left: 2rem; + padding-right: 2rem; + padding-bottom: 2rem; + padding-top: 1.75rem; + text-align: left; + color: var(--text-primary); + --tw-shadow: var(--shadow-modal); + --tw-shadow-colored: var(--shadow-modal); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + background-color: var(--color-modal-surface, var(--color-overlay-panel)); +} +.modal-sheet:focus-visible { + border-color: var(--color-border-translucent-bright); +} +@media (max-width: calc(1024px - var(--breakpoint-edge-offset))) { + + .modal-sheet { + inline-size: 100vw; + block-size: 100vh; + max-width: none; + max-height: none; + margin: 0; + border-radius: 0; + border: 0; + padding-top: calc(var(--space-lg) + env(safe-area-inset-top)); + padding-right: calc(var(--space-lg) + env(safe-area-inset-right)); + padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom)); + padding-left: calc(var(--space-lg) + env(safe-area-inset-left)); + overflow: auto; + } + } +#playerModal > .modal-sheet { + max-width: none; + width: 100%; + min-height: 100%; + padding: 0; + border-radius: 0; + box-shadow: none; + border: none; + background-color: var(--color-surface); + display: flex; + flex-direction: column; + align-items: stretch; + justify-content: flex-start; + flex: 1 1 auto; + } +#modalContainer > [id$="Modal"]:not(#playerModal) .modal-sheet { + z-index: var(--z-modal-content); + } +#modalContainer > #profileModal .modal-sheet, + #profileModal[data-modal-stack="top"] .modal-sheet { + z-index: var(--z-modal-top-content); + } +#modalContainer > #eventDetailsModal .modal-sheet { + z-index: var(--z-modal-top-content); + } +#shareNostrModal .modal-sheet { + z-index: var(--z-modal-peak-content); + } +#modalContainer > #loginModal .modal-sheet { + z-index: var(--z-modal-peak-content); + } +.modal-sheet { + position: relative; + margin-top: 0px; + margin-bottom: 0px; + width: 100%; + overflow: hidden; +} +#profileModal .modal-sheet { + width: 100%; + height: 100%; + max-width: none; + max-height: none; + border-radius: 0; + border: none; +} +.modal-sheet { + max-width: var(--modal-sheet-inline-max); + overscroll-behavior: contain; + } +@media (max-width: calc(1024px - var(--breakpoint-edge-offset))) { + .bv-modal { + align-items: stretch; + justify-content: stretch; + padding: 0; + } + + .bv-modal__panel, + .modal-sheet { + inline-size: 100vw; + block-size: 100vh; + max-width: none; + max-height: none; + margin: 0; + border-radius: 0; + border: 0; + padding-top: calc(var(--space-lg) + env(safe-area-inset-top)); + padding-right: calc(var(--space-lg) + env(safe-area-inset-right)); + padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom)); + padding-left: calc(var(--space-lg) + env(safe-area-inset-left)); + overflow: auto; + } + } +.modal-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-md); + padding-left: 2rem; + padding-right: 2rem; + padding-bottom: 1rem; + padding-top: 1.75rem; + background: transparent; + border: 0; +} +.modal-header[data-variant="flush"] { + padding-left: 0px; + padding-right: 0px; + padding-bottom: 0px; + padding-top: 0px; + background: transparent; +} +.modal-close { + outline: 2px solid transparent; + outline-offset: 2px; +} +.modal-close:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.modal-close { + display: flex; + height: 2.5rem; + width: 2.5rem; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + border: var(--border-width-hairline) solid + var(--color-border-translucent-medium); + background: var(--color-surface-tint-subtle); + color: var(--color-text-frosted-strong); +} +.modal-close:hover { + background: var(--color-border-translucent); + border-color: var(--color-border-translucent-stronger); + color: var(--color-text); + } +.modal-back { + display: inline-flex; + align-items: center; + gap: 0.5rem; +} +@media (min-width: 1024px) { + .modal-back { + display: none !important; + } + } +.modal-body > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.25rem * var(--tw-space-y-reverse)); +} +.modal-body { + padding-left: 2rem; + padding-right: 2rem; + padding-bottom: 2rem; + padding-top: 0.5rem; + overscroll-behavior: contain; + scrollbar-width: thin; +} +.modal-body::-webkit-scrollbar { + width: var(--scrollbar-thin-width); + } +.modal-body::-webkit-scrollbar-track { + background: transparent; + } +.modal-body::-webkit-scrollbar-thumb { + background: var(--color-border-translucent); + border-radius: var(--radius-full); + } +/* Modal embed containers ensure iframe wrappers respect modal sizing tokens. */ +.modal-embed-frame { + display: flex; + height: var(--modal-embed-height); + max-height: var(--modal-embed-height); + width: 100%; + flex-direction: column; +} +.modal-footer { + display: flex; + flex-direction: column; + gap: 0.75rem; + padding-left: 2rem; + padding-right: 2rem; + padding-bottom: 2rem; + padding-top: 1rem; +} +.modal-alert { + display: flex; + align-items: flex-start; + gap: 0.75rem; + border-radius: var(--radius-md); + border-width: 1px; + border-color: var(--status-warning-strong); + --tw-border-opacity: 0.6; + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--status-warning-strong); + backdrop-filter: blur(var(--blur-modal-alert)); + background-color: var(--color-warning-glass); +} +.modal-alert__icon { + margin-top: 0.125rem; + height: 1.25rem; + width: 1.25rem; + flex-shrink: 0; + color: var(--status-warning-strong); +} +.modal-tile { + border-radius: var(--radius-xl); + border-width: 1px; + border-color: var(--border-overlay); + background-color: var(--surface-overlay-panel-soft); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 1rem; + padding-bottom: 1rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-frosted-primary); + background-color: var(--color-overlay-panel-glass-soft); +} +.modal-tile > h3 { + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--text-primary); +} +.modal-primary { + outline: 2px solid transparent; + outline-offset: 2px; +} +.modal-primary:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.modal-primary { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: var(--color-accent-strong); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 0.625rem; + padding-bottom: 0.625rem; + font-size: var(--font-size-base); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--color-white); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.modal-primary[data-size="sm"] { + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + gap: 0.375rem; +} +.modal-primary:hover { + background-color: var(--color-accent); +} +.modal-primary:focus-visible { + background-color: var(--color-accent-pressed); +} +.modal-primary:disabled { + pointer-events: none; + cursor: not-allowed; + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +body.iframe-form button.modal-primary { + align-self: flex-start; + margin-top: var(--space-md); + } +.modal-primary { + width: 100%; + justify-content: center; +} +@media (prefers-reduced-motion: reduce) { + + .modal-primary { + transition-property: none; + } +} +.grid-stack { + display: grid; + gap: var(--space-lg); +} +.grid-stack[data-variant="cards"] { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} +@media (min-width: 640px) { + .grid-stack[data-variant="cards"] { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} +@media (min-width: 1280px) { + .grid-stack[data-variant="cards"] { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } +} +.grid-stack[data-orientation="vertical"] { + display: flex; + flex-direction: column; + gap: var(--space-md); +} +.bv-stack { + display: flex; + flex-direction: column; + gap: var(--space-lg); +} +.bv-stack--tight { + gap: var(--space-md); +} +.bv-grid-video { + display: grid; + gap: var(--space-xl); + padding-top: var(--space-lg); + padding-bottom: var(--space-lg); + grid-template-columns: repeat( + auto-fill, + minmax(var(--grid-card-min-width), 1fr) + ); +} +.\!card[data-alert="nsfw-owner"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--color-black); +} +.card[data-alert="nsfw-owner"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--color-black); +} +.\!card[data-alert="nsfw-owner"]:hover { + --tw-border-opacity: 0.6; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.card[data-alert="nsfw-owner"]:hover { + --tw-border-opacity: 0.6; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.\!card img[data-thumbnail-state="blurred"], + .\!card img[data-visual-state="blurred"] { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.card img[data-thumbnail-state="blurred"], + .card img[data-visual-state="blurred"], + .channel-profile-container img[data-visual-state="blurred"] { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.\!card img[data-thumbnail-state="blurred"], + .\!card img[data-visual-state="blurred"] { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + filter: blur(var(--blur-thumbnail-blur)) !important; + transform: scale(1.05) !important; +} +.card img[data-thumbnail-state="blurred"], + .card img[data-visual-state="blurred"], + .channel-profile-container img[data-visual-state="blurred"] { + filter: blur(var(--blur-thumbnail-blur)); + transform: scale(1.05); + } +.\!card img[data-thumbnail-state="blurred"], + .\!card img[data-visual-state="blurred"] { + filter: blur(var(--blur-thumbnail-blur)) !important; + transform: scale(1.05) !important; + } +.channel-moderation-badge-anchor { + display: flex; + flex-direction: column; + gap: var(--space-sm); + pointer-events: none; + width: 100%; +} +.channel-moderation-badge-anchor:empty { + display: none; + } +.channel-moderation-badge-anchor > [data-moderation-badge="true"] { + pointer-events: auto; + max-width: min(100%, var(--moderation-badge-max-inline)); + } +#playerModal .video-modal__video { + position: relative; + } +#playerModal + .video-modal__video[data-visual-state="blurred"] + .video-modal__media { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + filter: blur(var(--blur-thumbnail-blur)); + transform: scale(1.05); +} +#playerModal .video-modal__moderation-bar { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + padding-bottom: var(--space-md); + } +#playerModal .video-modal__moderation-bar[hidden] { + display: none; + } +#playerModal .video-modal__moderation-bar .moderation-badge { + width: 100%; + max-width: none; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + gap: var(--space-sm); + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + } +#playerModal .video-modal__moderation-bar .moderation-badge__label { + flex: 1 1 auto; + } +#playerModal .video-modal__moderation-bar .moderation-badge__actions { + flex-shrink: 0; + } +.\!card[data-owner-is-viewer="true"][data-url-health-state="offline"][data-stream-health-state="unhealthy"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +.card[data-owner-is-viewer="true"][data-url-health-state="offline"][data-stream-health-state="unhealthy"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +.video-visibility-toggle { + display: inline-flex; + align-items: center; + gap: 0.25rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-default); + background-color: var(--surface-panel); + padding-left: 0.25rem; + padding-right: 0.25rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} +.video-visibility-toggle__option { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + background-color: var(--surface-panel); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: uppercase; + color: var(--text-muted); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); +} +.video-visibility-toggle__option:not(.is-disabled):hover { + background-color: var(--surface-panel-hover); + color: var(--text-primary); +} +.video-visibility-toggle__option[data-active="true"] { + border-width: 1px; + border-color: var(--color-accent); + --tw-border-opacity: 0.6; + color: var(--text-primary); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.video-visibility-toggle__option.is-disabled { + cursor: not-allowed; + opacity: 0.45; +} +.video-modal__container { + display: flex; + height: 100%; + min-height: 100vh; + width: 100%; + flex: 1 1 0%; + flex-direction: column; +} +.player-modal__container { + display: flex; + height: 100%; + min-height: 100vh; + width: 100%; + flex: 1 1 0%; + flex-direction: column; + gap: 1.5rem; +} +#playerModal { + --player-modal-vertical-padding: var(--space-md-plus); + --player-modal-primary-inline-padding-lg: clamp( + var(--space-sm), + 2.75vw, + var(--space-lg) + ); + } +#playerModal > .bv-modal__panel { + max-width: none; + width: 100%; + min-height: 100%; + padding: 0; + border-radius: 0; + box-shadow: none; + border: none; + background-color: var(--color-surface); + display: flex; + flex-direction: column; + align-items: stretch; + justify-content: flex-start; + flex: 1 1 auto; + } +.video-modal__panel { + position: relative; + z-index: var(--z-modal-content); + display: flex; + flex: 1 1 auto; + width: 100%; + min-height: 100%; + flex-direction: column; + overflow: visible; + padding: 0; + margin: 0; + border: none; + border-radius: 0; + background-color: var(--color-surface); + box-shadow: none; + } +#playerModal .watch-container { + width: 100%; + max-width: var(--player-modal-inline-max, var(--layout-player-max-width)); + margin-inline: auto; + padding-inline: var( + --player-modal-inline-padding, + clamp(var(--space-md), 4vw, var(--space-xl-plus)) + ); + overflow: visible; + } +#playerModal .watch-container.video-modal__similar { + padding-inline: clamp(var(--space-3xs), 0.6vw, var(--space-2xs)); + } +#playerModal .video-modal__primary > .watch-container:first-child { + padding-block-start: var(--player-modal-vertical-padding); + } +#playerModal .video-modal__primary > .watch-container:last-child { + padding-block-end: var(--player-modal-vertical-padding); + } +#playerModal .video-modal__secondary > .watch-container:last-child { + padding-block-end: var(--player-modal-vertical-padding); + } +#playerModal .modal-nav .watch-container { + max-width: none; + margin-inline: 0; + } +#playerModal .modal-info-panel { + display: flex; + flex-direction: column; + gap: var(--space-md-plus); + } +#playerModal h2#videoTitle { + margin: 0; + font-size: clamp( + var(--font-size-xl), + calc(var(--font-size-modal-title-base) + 0.5vw), + var(--font-size-xl-plus) + ); + font-weight: 600; + line-height: 1.3; + color: var(--color-text); + min-width: 0; + overflow-wrap: break-word; + word-break: break-word; + } +@media (min-width: 1024px) { + .video-modal__headline #videoTitle.video-modal__title { + flex: 1 1 0%; + min-width: 0; + max-width: calc(100% - var(--space-3xl) - var(--space-md)); + } + + .video-modal__headline .video-modal__status { + flex: 0 0 auto; + max-width: clamp(var(--space-xl), 25%, var(--space-3xl)); + margin-left: auto; + } + } +#playerModal .modal-meta { + font-size: var(--font-size-sm); + line-height: 1.4; + color: var(--color-text-muted); + } +#playerModal .modal-view-count { + font-weight: 600; + color: var(--color-text); + } +#playerModal .channel-card { + display: flex; + align-items: center; + gap: var(--space-md); + padding: var(--space-md) var(--space-lg); + border-radius: var(--radius-xl); + border: var(--border-width-hairline) solid var(--color-border-translucent); + background-color: var(--color-surface); + box-shadow: var(--shadow-sm); + } +#playerModal .player-modal__module { + display: flex; + flex-direction: column; + gap: clamp(var(--space-2xs), 1vw, var(--space-sm)); + width: 100%; + padding: clamp(var(--space-xs), 1vw, var(--space-sm)); + border-radius: var(--radius-xl); + border: var(--border-width-hairline) solid var(--color-border-translucent); + background-color: var(--color-surface); + box-shadow: var(--shadow-sm); + } +#playerModal .player-modal__module-title { + margin: 0; + font-size: var(--font-size-lg); + font-weight: 600; + line-height: 1.3; + color: var(--color-text); + } +#playerModal .player-modal__module-list { + display: flex; + flex-direction: column; + gap: var(--space-sm); + width: 100%; + margin: 0; + padding: 0; + list-style: none; + } +#playerModal .video-modal__similar .player-modal__module { + gap: clamp(var(--space-3xs), 0.6vw, var(--space-xs)); + padding: clamp(var(--space-2xs), 0.6vw, var(--space-xs)); + border-width: 0; + box-shadow: none; + background-color: transparent; + } +#playerModal .video-modal__similar .player-modal__module-title { + padding-inline: clamp(var(--space-3xs), 0.6vw, var(--space-2xs)); + } +#playerModal .video-modal__similar .player-modal__module-list { + gap: clamp(var(--space-3xs), 0.6vw, var(--space-xs)); + padding-inline: clamp(var(--space-3xs), 0.6vw, var(--space-2xs)); + padding-bottom: clamp(var(--space-3xs), 0.6vw, var(--space-2xs)); + } +#playerModal .player-modal__module-scroll { + max-height: clamp( + var(--player-modal-module-scroll-min-height), + calc( + 100vh - (var(--player-modal-vertical-padding) * 2) - var(--space-2xl) + ), + var(--player-modal-module-scroll-max-height) + ); + overflow-y: auto; + overflow-x: hidden; + overscroll-behavior: contain; + scrollbar-gutter: stable; + padding-inline-end: var(--space-xs); + } +#playerModal .video-modal__similar .player-modal__module-scroll { + max-height: none; + overflow: visible; + padding-inline-end: 0; + scrollbar-gutter: auto; + } +#playerModal .player-modal__module-scroll > li { + scroll-margin-block: var(--space-xs); + } +@media (max-width: 480px) { + #playerModal .modal-nav .icon-button { + width: var(--space-xl); + height: var(--space-xl); + min-width: var(--space-xl); + min-height: var(--space-xl); + } + + #playerModal .watch-container { + padding-inline: var(--space-sm); + } + + #playerModal .channel-card { + gap: var(--space-sm); + padding: var(--space-sm) var(--space-md); + } + } +#playerModal .channel-card__avatar { + flex-shrink: 0; + width: var(--avatar-size-lg); + height: var(--avatar-size-lg); + border-radius: var(--radius-full); + overflow: hidden; + background-color: var(--color-border-subtle); + } +#playerModal .channel-card__avatar img { + display: block; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + } +#playerModal .channel-card__name { + margin: 0; + font-size: var(--font-size-lg); + font-weight: 600; + color: var(--color-text); + } +#playerModal .channel-card__npub { + margin: 0; + font-size: var(--font-size-sm); + color: var(--color-text-muted); + } +#playerModal .description-panel { + padding: var(--space-md-plus) var(--space-lg); + border-radius: var(--radius-xl); + border: var(--border-width-hairline) solid var(--color-border-translucent); + background-color: var(--color-surface); + box-shadow: var(--shadow-sm); + } +#playerModal .description-panel p { + margin: 0; + font-size: var(--font-size-sm); + line-height: 1.6; + color: var(--color-text); + } +.player-modal__content { + position: relative; + z-index: var(--z-modal-content); + display: flex; + flex: 1 1 auto; + width: 100%; + min-height: 100%; + flex-direction: column; + overflow: visible; + padding: 0; + margin: 0; + border: none; + border-radius: 0; + background-color: var(--color-surface); + box-shadow: none; + } +@media (prefers-reduced-motion: reduce) { + + .player-modal__content { + transition-property: none; + } +} +#playerModal .modal-nav { + position: sticky; + top: 0px; + z-index: var(--z-overlay-nav); + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + background-color: var(--surface-overlay-panel); + background-image: linear-gradient( + 180deg, + color-mix(in srgb, var(--surface-overlay-panel) 94%, transparent) 0%, + color-mix(in srgb, var(--surface-overlay-panel) 88%, transparent) 100% + ); + border-bottom: var(--border-width-hairline) solid var(--border-overlay); + backdrop-filter: blur(var(--modal-nav-backdrop-blur)); + -webkit-backdrop-filter: blur(var(--modal-nav-backdrop-blur)); +} +#playerModal .modal-nav__bar { + display: flex; + width: 100%; + align-items: center; + justify-content: flex-start; + gap: 0.5rem; + padding-block: var(--space-xs); + padding-inline: clamp(var(--space-sm), 2.5vw, var(--space-lg)); +} +#playerModal .modal-nav__rail { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 0.5rem; +} +#playerModal .modal-nav__slot { + display: flex; + align-items: center; + gap: 0.5rem; +} +#playerModal .modal-nav__slot--context { + justify-content: flex-end; + margin-inline-start: auto; + min-inline-size: 0; +} +#playerModal .modal-nav__context { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.025em; + color: var(--text-muted); +} +#playerModal .modal-nav .modal-actions { + display: flex; + align-items: center; + gap: 0.5rem; + margin-left: 0; + align-self: stretch; +} +#playerModal .modal-nav .icon-button { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + color: var(--text-muted); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + inline-size: var(--icon-size-md); + block-size: var(--icon-size-md); + background: var(--surface-overlay-panel-tint); + border: var(--border-width-hairline) solid var(--border-overlay); + color: var(--color-text-muted); +} +#playerModal .modal-nav .icon-button:hover, + #playerModal .modal-nav .icon-button:focus-visible { + background: var(--surface-overlay-panel-soft); + border-color: var(--border-overlay-strong); + color: var(--color-text); + } +.modal-nav--hidden { + --tw-translate-y: -100%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.modal-nav--visible { + --tw-translate-y: 0px; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.video-modal__layout { + --video-modal-secondary-size: clamp( + var(--video-modal-secondary-min), + 46vw, + var(--video-modal-secondary-max) + ); + --video-modal-gap: clamp(var(--space-2xs), 0.85vw, var(--space-sm)); + display: grid; + gap: var(--video-modal-gap); + width: min(100%, var(--video-modal-layout-max)); + margin-inline: auto; + grid-template-columns: minmax(0, 1fr); + grid-template-areas: + "primary" + "secondary"; + align-items: start; + } +@media (min-width: 1024px) { + .video-modal__layout { + --video-modal-secondary-size: clamp( + var(--video-modal-secondary-min), + 30vw, + var(--video-modal-secondary-max) + ); + grid-template-columns: + minmax(0, 1fr) + minmax( + var(--video-modal-secondary-min), + var(--video-modal-secondary-size) + ); + grid-template-areas: "primary secondary"; + align-items: stretch; + grid-auto-flow: column; + } + + .video-modal__primary { + min-width: 0; + min-height: 0; + grid-area: primary; + } + + .video-modal__secondary { + min-width: var(--video-modal-secondary-min); + min-height: 0; + max-width: var(--video-modal-secondary-size); + grid-area: secondary; + height: 100%; + } + + #playerModal .video-modal__layout .watch-container { + max-width: none; + margin-inline: 0; + width: 100%; + } + } +@media (min-width: 1280px) { + .video-modal__layout { + --video-modal-secondary-size: clamp( + var(--video-modal-secondary-min), + 28vw, + var(--video-modal-secondary-max) + ); + } + } +#playerModal .video-modal__layout { + display: grid; + } +@media (min-width: 1024px) { + #playerModal .video-modal__layout { + grid-template-columns: + minmax(0, 1fr) + minmax( + var(--video-modal-secondary-min), + var(--video-modal-secondary-size) + ); + grid-template-areas: "primary secondary"; + align-items: stretch; + grid-auto-flow: column; + } + + #playerModal .video-modal__primary { + grid-area: primary; + } + + #playerModal .video-modal__secondary { + grid-area: secondary; + } + #playerModal .video-modal__primary { + --player-modal-inline-padding: var( + --player-modal-primary-inline-padding-lg, + clamp(var(--space-sm), 2.75vw, var(--space-lg)) + ); + } + + #playerModal .modal-nav__bar { + --player-modal-inline-padding: var( + --player-modal-primary-inline-padding-lg, + clamp(var(--space-sm), 2.75vw, var(--space-lg)) + ); + } + } +.revert-modal__layout { + display: grid; + gap: 1.5rem; +} +@media (min-width: 1024px) { + .revert-modal__layout { + grid-template-columns: + minmax( + var(--revert-modal-sidebar-min), + var(--revert-modal-sidebar-width) + ) + minmax(0, 1fr); + } + } +.video-modal__primary { + display: flex; + flex-direction: column; + gap: 1.5rem; + min-width: 0; + min-height: 0; +} +.video-modal__secondary { + display: flex; + flex-direction: column; + gap: 1rem; + min-width: 0; + min-height: 0; + width: 100%; + align-self: stretch; +} +.video-modal__similar { + display: none; + } +@media (min-width: 1024px) { + .video-modal__similar { + display: flex; + flex-direction: column; + gap: 1.5rem; + align-self: stretch; + flex: 1 1 auto; + min-height: 0; + } + #playerModal .video-modal__similar .player-modal__module { + height: 100%; + display: flex; + flex: 1 1 auto; + min-height: 0; + flex-direction: column; + } + + #playerModal .video-modal__similar .player-modal__module-list { + flex: 1 1 auto; + min-height: 0; + } + + #playerModal .video-modal__similar .player-modal__module-scroll { + height: 100%; + max-height: none; + min-height: 0; + } + } +#playerModal .player-modal__module-item { + width: 100%; + } +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) { + display: flex; + width: 100%; + flex-direction: row; + flex-wrap: nowrap; + align-items: stretch; + gap: var(--space-md); +} +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) { + display: flex; + width: 100%; + flex-direction: row; + flex-wrap: nowrap; + align-items: stretch; + gap: var(--space-md); +} +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) + .video-card__media { + width: clamp( + var(--video-modal-item-media-min), + 18vw, + var(--video-modal-item-media-max) + ); + } +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) + .video-card__media { + width: clamp( + var(--video-modal-item-media-min), + 18vw, + var(--video-modal-item-media-max) + ) !important; + } +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) + .video-card__media { + flex-shrink: 0; + overflow: hidden; + border-radius: var(--radius-lg); +} +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) + .video-card__media { + flex-shrink: 0; + overflow: hidden; + border-radius: var(--radius-lg); +} +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) + .video-card__content { + padding: clamp(var(--space-sm), 1.25vw, var(--space-md)); + } +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) + .video-card__content { + padding: clamp(var(--space-sm), 1.25vw, var(--space-md)) !important; + } +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) + .video-card__content { + display: flex; + min-width: 0px; + flex: 1 1 0%; + flex-direction: column; + gap: var(--space-sm); +} +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) + .video-card__content { + display: flex; + min-width: 0px; + flex: 1 1 0%; + flex-direction: column; + gap: var(--space-sm); +} +#playerModal + .player-modal__module-item + > .card:not(.player-modal__similar-card) + .video-card__meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + color: var(--text-muted-strong); +} +#playerModal + .player-modal__module-item + > .\!card:not(.player-modal__similar-card) + .video-card__meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + color: var(--text-muted-strong); +} +#playerModal .video-modal__similar .player-modal__module-list { + gap: clamp(var(--space-2xs), 0.85vw, var(--space-sm)); + } +.player-modal__similar-card { + outline: 2px solid transparent; + outline-offset: 2px; +} +.player-modal__similar-card:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.player-modal__similar-card { + position: relative; + display: flex; + width: 100%; + min-width: 0px; + align-items: flex-start; + gap: 0.75rem; + border-radius: var(--radius-xl); + padding: 0.5rem; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.player-modal__similar-card:hover, + .player-modal__similar-card:focus-within { + background-color: var(--surface-panel-hover); + } +.player-modal__similar-card-media { + position: relative; + display: block; + flex-shrink: 0; + overflow: hidden; + border-radius: var(--radius-lg); + background-color: var(--surface-alt); + width: var(--similar-card-media-width); + aspect-ratio: 16 / 9; + background-image: var(--similar-card-thumb-url, none); + background-position: center; + background-size: cover; +} +@media (max-width: 640px) { + .player-modal__similar-card-media { + width: var(--similar-card-media-width-sm); + } + } +.player-modal__similar-card-media img { + display: block; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + border-radius: inherit; + } +.player-modal__similar-card-content { + display: flex; + min-width: 0px; + flex: 1 1 0%; + flex-direction: column; + gap: 0.25rem; +} +.player-modal__similar-card-title { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + line-height: 1.375; + color: var(--text-primary); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + min-width: 0; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} +.player-modal__similar-card:hover .player-modal__similar-card-title, + .player-modal__similar-card-title:focus-visible { + color: var(--color-accent-strong); + } +.player-modal__similar-card-author { + display: flex; + min-width: 0px; + align-items: center; +} +.player-modal__similar-card-author-meta { + display: flex; + min-width: 0px; + flex-direction: column; +} +.player-modal__similar-card-author-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 500; + color: var(--text-muted); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.player-modal__similar-card:hover .player-modal__similar-card-author-name { + color: var(--color-text-strong); +} +/* Hidden for now to match cleaner modern look, but kept in DOM if needed */ +.player-modal__similar-card-author-npub { + display: none; + } +.player-modal__similar-card-meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.25rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + color: var(--text-muted-strong); + min-width: 0; +} +.player-modal__similar-card-timestamp { + white-space: nowrap; + } +.video-modal__stage { + position: relative; + isolation: isolate; + overflow: visible; + --video-modal-ambient-bleed: clamp( + var(--space-2xl), + 12vw, + var(--space-5xl) + ); + --video-modal-ambient-scale: 1.38; + --video-modal-ambient-blur: clamp( + var(--video-modal-ambient-blur-min), + 20vw, + var(--video-modal-ambient-blur-max) + ); + --video-modal-ambient-opacity: 1; + } +.video-modal__video { + position: relative; + z-index: 1; + border-radius: var(--radius-xl); + padding-block: clamp(var(--space-xs), 2.5vw, var(--space-md-plus)); + background-color: transparent; + box-shadow: 0 0 0 var(--border-width-hairline) + color-mix(in srgb, var(--color-border-strong) 8%, transparent) inset; + overflow: visible; + } +.video-modal__ambient { + position: absolute; + inset: calc(var(--video-modal-ambient-bleed) * -1); + border-radius: calc(var(--radius-3xl) + var(--video-modal-ambient-bleed)); + pointer-events: none; + z-index: 0; + display: block; + overflow: visible; + } +.video-modal__ambient::before { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + background: radial-gradient( + circle at 50% 50%, + color-mix(in srgb, var(--color-overlay-strong) 18%, transparent) 0%, + color-mix(in srgb, var(--color-overlay) 34%, transparent) 62%, + transparent 100% + ); + opacity: 0.9; + mix-blend-mode: screen; + pointer-events: none; + } +.video-modal__ambient-canvas { + position: relative; + width: 100%; + height: 100%; + display: block; + transform: scale(var(--video-modal-ambient-scale)); + filter: blur(var(--video-modal-ambient-blur)) saturate(2) brightness(1.24); + opacity: var(--video-modal-ambient-opacity); + } +@media (min-width: 1024px) { + .video-modal__video { + position: sticky; + top: calc(var(--space-2xl) + var(--space-3xl)); + z-index: 1; + } + + .video-modal__status { + flex-basis: clamp(var(--space-xl), 25%, var(--space-3xl)); + max-width: clamp(var(--space-xl), 25%, var(--space-3xl)); + } + + .video-modal__details { + position: relative; + z-index: 2; + margin-top: var(--space-lg); + } + } +#playerModal .video-modal__video video { + position: relative; + z-index: 1; + background-color: var(--color-black); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-video-modal); + max-height: min(80vh, calc(100vw * 9 / 16)); + -o-object-fit: contain; + object-fit: contain; + } +.video-modal__media { + display: block; + aspect-ratio: 16 / 9; + width: 100%; + -o-object-fit: contain; + object-fit: contain; + } +.video-modal__details { + display: flex; + flex-direction: column; + gap: 1.5rem; +} +.video-modal__meta { + border-bottom-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.2; + padding-bottom: 1rem; +} +/* Video modal tag strip */ +.video-modal__tags { + margin-left: -0.25rem; + margin-right: -0.25rem; + display: flex; + gap: 0.5rem; + padding-left: 0.25rem; + padding-right: 0.25rem; +} +.video-modal__similar .video-modal__tags { + margin-bottom: clamp(var(--space-xs), 0.9vw, var(--space-md)); + } +.video-modal__tags[hidden] { + display: none; + } +.video-modal__tags[data-fade] { + position: relative; + } +.video-modal__tags[data-fade]::before, + .video-modal__tags[data-fade]::after { + content: ""; + position: sticky; + top: 0; + bottom: 0; + width: var(--space-lg); + pointer-events: none; + z-index: 1; + } +.video-modal__tags[data-fade]::before { + left: 0; + background: linear-gradient( + to right, + var(--surface-overlay-muted), + transparent + ); + } +.video-modal__tags[data-fade]::after { + right: 0; + background: linear-gradient( + to left, + var(--surface-overlay-muted), + transparent + ); + } +.video-tag-strip { + display: flex; + flex-wrap: nowrap; + align-items: center; + gap: var(--space-xs); + overflow: hidden; + } +.video-tag-strip--scroll { + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + padding-bottom: var(--space-xs); + scrollbar-width: none; + -ms-overflow-style: none; + } +.video-tag-strip--scroll::-webkit-scrollbar { + display: none; + width: 0; + height: 0; + } +.video-tag-pill { + display: inline-flex; + align-items: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--status-neutral-border); + background-color: var(--status-neutral-surface); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + font-weight: 500; + color: var(--status-neutral-on); + position: relative; + justify-content: center; + white-space: nowrap; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + min-height: calc(var(--space-sm) + var(--space-xs)); + margin-inline-end: 0.25rem; +} +.video-tag-pill__label { + transition-property: opacity; + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; +} +.video-tag-pill__icon { + position: absolute; + inset: 0px; + display: flex; + align-items: center; + justify-content: center; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + opacity: 0; + transform: scale(0.8); +} +.video-tag-pill__icon svg { + height: 0.75rem; + width: 0.75rem; +} +.video-tag-pill:hover .video-tag-pill__label, + .video-tag-pill:focus-visible .video-tag-pill__label { + opacity: 0; + } +.video-tag-pill:hover .video-tag-pill__icon, + .video-tag-pill:focus-visible .video-tag-pill__icon { + opacity: 1; + transform: scale(1); + } +.video-modal__actions-row { + display: flex; + width: 100%; + flex-wrap: wrap; + align-items: flex-start; + -moz-column-gap: 0.75rem; + column-gap: 0.75rem; + row-gap: 0.75rem; +} +@media (min-width: 640px) { + .video-modal__actions-row { + -moz-column-gap: 1rem; + column-gap: 1rem; + } +} +.video-modal__reactions, + .video-modal__actions-group { + flex: 1 1 var(--menu-min-width); + min-inline-size: 0; + } +.video-modal__reactions { + display: flex; + flex-basis: 100%; + flex-wrap: wrap; + align-items: flex-start; + gap: 0.75rem; +} +@media (min-width: 640px) { + .video-modal__reactions { + gap: 1rem; + } +} +@media (min-width: 768px) { + .video-modal__reactions { + flex-basis: auto; + } +} +.video-modal__reaction-buttons { + display: inline-flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; +} +.video-modal__reaction-button { + --video-modal-reaction-active-bg: color-mix( + in srgb, + var(--color-accent) 22%, + var(--surface-overlay-panel) + ); + --video-modal-reaction-active-border: color-mix( + in srgb, + var(--color-accent) 38%, + var(--border-overlay) + ); + } +.video-modal__reaction-button[aria-pressed="true"] { + color: var(--color-accent-strong); + background-color: var(--video-modal-reaction-active-bg); + border-color: var(--video-modal-reaction-active-border); + } +.video-modal__reaction-button[aria-pressed="true"] + .video-modal__reaction-count { + color: var(--color-accent-strong); + } +.video-modal__reaction-count { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + color: var(--text-muted); +} +.video-modal__reaction-meter { + display: flex; + align-items: center; + gap: var(--space-sm); + flex-wrap: wrap; + flex: 1 1 var(--menu-min-width); + max-inline-size: 100%; + } +.video-modal__reaction-meter-label { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 500; + color: var(--text-muted); + min-inline-size: var(--video-modal-reaction-label-min-inline); +} +.video-modal__reaction-meter-track { + position: relative; + flex: 1 1 auto; + inline-size: 100%; + block-size: var(--space-xs); + border-radius: var(--radius-full); + background-color: var(--color-border-muted); + overflow: hidden; + } +.video-modal__reaction-meter-fill { + position: absolute; + inset-inline-start: 0; + inset-block-start: 0; + block-size: 100%; + max-inline-size: 100%; + inline-size: var(--video-modal-reaction-fill, 0%); + width: var(--video-modal-reaction-fill, 0%); + background-image: linear-gradient( + 90deg, + var(--color-accent) 0%, + var(--color-accent-strong) 100% + ); + transition: inline-size var(--motion-duration-base) var(--motion-ease-out); + } +.video-modal__reaction-meter-fill--empty { + inline-size: 0%; + width: 0%; + } +.video-modal__actions-group { + display: flex; + flex-basis: 100%; + flex-wrap: wrap; + align-items: flex-start; + justify-content: flex-start; + gap: 0.75rem; +} +@media (min-width: 768px) { + .video-modal__actions-group { + flex-basis: auto; + justify-content: flex-end; + margin-inline-start: auto; + } +} +.video-modal__action-button { + display: inline-flex; + height: 2.75rem; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + min-width: var(--video-modal-action-min-width); + padding-inline: var(--space-md); + border-width: var(--border-width-hairline); + border-style: solid; +} + + .bv-modal.video-modal__action-label { + display: none; + } +.profile-pane.video-modal__action-label { + display: none; + } +.video-modal__action-label { + display: none; +} +@media (min-width: 640px) { + .video-modal__action-label { + display: inline; + } +} +.video-modal__action-icon { + height: 1.25rem; + width: 1.25rem; +} +.video-modal__channel, + .video-modal__description, + .video-modal__stats { + border-radius: 1rem; + border-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.2; + background-color: var(--surface-base); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 1rem; + padding-bottom: 1rem; + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.video-modal__description-body { + overflow-wrap: anywhere; + word-break: break-word; + } +.video-modal__description-body a { + color: var(--color-accent-strong); + text-decoration: underline; + text-decoration-color: currentColor; + word-break: break-word; + } +.video-modal__description-body a:hover, + .video-modal__description-body a:focus-visible { + color: var(--color-accent-pressed); + } +.video-modal__comments { + border-radius: 1rem; + border-width: 1px; + border-color: var(--border-default); + --tw-border-opacity: 0.2; + background-color: var(--surface-base); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 1.25rem; + padding-bottom: 1.25rem; + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + display: flex; + flex-direction: column; + gap: var(--space-lg); +} +.comment-thread { + display: flex; + flex-direction: column; + gap: var(--space-lg); + } +.comment-thread__header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: var(--space-sm); + } +.comment-thread__title { + font-size: var(--font-size-lg); + line-height: var(--line-height-base); + font-weight: 600; + color: var(--text-primary); +} +.comment-thread__count { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-muted); + margin: 0; +} +.comment-thread__empty { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-muted); + margin: 0; + padding: var(--space-md); + border-radius: var(--radius-lg); + border: var(--border-width-hairline) dashed + color-mix(in srgb, var(--border-default) 40%, transparent); + background-color: var(--surface-alt); +} +.comment-thread__list { + display: flex; + flex-direction: column; + gap: var(--space-md); + margin: 0; + padding: 0; + list-style: none; + } +.comment-thread__item { + display: grid; + grid-template-columns: auto 1fr; + gap: var(--space-md); + padding-block: var(--space-sm); + border-bottom: var(--border-width-hairline) solid var(--border-subtle); + } +.comment-thread__item:last-child { + border-bottom: none; + padding-bottom: 0; + } +.comment-thread__avatar { + inline-size: var(--comment-avatar-size); + block-size: var(--comment-avatar-size); + } +.comment-thread__avatar img { + border-radius: var(--radius-full); + -o-object-fit: cover; + object-fit: cover; + inline-size: 100%; + block-size: 100%; +} +.comment-thread__content { + display: flex; + flex-direction: column; + gap: var(--space-xs); + min-inline-size: 0; + } +.comment-thread__meta { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + color: var(--text-muted); + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-xs); +} +.comment-thread__author { + font-weight: 600; + color: var(--text-primary); + } +.comment-thread__timestamp { + color: var(--text-muted); + } +.comment-thread__body { + color: var(--text-primary); + line-height: 1.6; + word-break: break-word; + } +.comment-thread__actions { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-sm); +} +.comment-thread__actions button { + outline: 2px solid transparent; + outline-offset: 2px; +} +.comment-thread__actions button:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.comment-thread__actions button { + display: inline-flex; + align-items: center; + gap: 0.25rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-base); + padding-left: 0.75rem; + padding-right: 0.75rem; + padding-top: 0.25rem; + padding-bottom: 0.25rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 600; + color: var(--text-muted); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.comment-thread__actions button:hover, + .comment-thread__actions button:focus-visible { + color: var(--text-primary); + border-color: var(--border-default); + } +.comment-thread__replies { + display: flex; + flex-direction: column; + gap: var(--space-md); + margin: 0; + margin-inline-start: calc(var(--space-lg) + var(--space-sm)); + padding-inline-start: var(--space-md); + padding-block-start: var(--space-md); + border-inline-start: var(--border-width-hairline) solid var(--border-subtle); + list-style: none; + } +.comment-thread__load-more { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + border-radius: var(--radius-full); + border-width: 1px; + border-color: var(--border-subtle); + background-color: var(--surface-base); + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + color: var(--text-primary); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +.comment-thread__load-more:hover, + .comment-thread__load-more:focus-visible { + border-color: var(--border-default); + color: var(--text-primary); + background-color: color-mix(in srgb, var(--surface-alt) 70%, transparent); + } +.comment-thread__disabled { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-muted); + border-radius: var(--radius-lg); + border: var(--border-width-hairline) dashed + color-mix(in srgb, var(--border-default) 32%, transparent); + background-color: var(--surface-alt); + padding: var(--space-md); +} +.comment-composer { + display: flex; + flex-direction: column; + gap: var(--space-md); + border-top: var(--border-width-hairline) solid var(--border-subtle); + padding-top: var(--space-lg); + } +.comment-composer__field { + display: flex; + flex-direction: column; + gap: var(--space-2xs); + } +.comment-composer__label { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + color: var(--text-primary); +} +.comment-composer__textarea { + min-block-size: var(--comment-composer-min-height); + } +.comment-composer__footer { + display: flex; + flex-direction: column; + gap: var(--space-sm); + } +.comment-composer__hint { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + color: var(--text-muted); + margin: 0; +} +.comment-composer__actions { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: flex-end; + gap: var(--space-sm); + } +.comment-composer__char-count { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + font-weight: 500; + color: var(--text-muted); +} +.comment-composer__submit { + outline: 2px solid transparent; + outline-offset: 2px; +} +.comment-composer__submit:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.comment-composer__status { + margin: 0; + } +@media (min-width: 640px) { + .comment-composer__footer { + flex-direction: row; + align-items: center; + justify-content: space-between; + } + } +.video-modal__progress { + height: 0.5rem; + width: 100%; + overflow: hidden; + border-radius: var(--radius-full); + background-color: var(--border-subtle); +} +.video-modal__stat-metrics { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 0.75rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-muted); +} +.profile-modal { + display: flex; + flex-direction: column; + inline-size: 100%; + block-size: 100%; + min-block-size: 100%; + max-block-size: none; + overflow: hidden; + --modal-sheet-inline-max: var(--profile-modal-inline-max); + --profile-modal-scale: 0.9; + --profile-modal-gap: calc( + (var(--space-md) - var(--space-3xs)) * var(--profile-modal-scale) + ); + --profile-modal-padding-inline: calc( + (var(--space-lg) - var(--space-md)) * var(--profile-modal-scale) + ); + --profile-modal-padding-block-start: calc( + (var(--space-md) - var(--space-2xs)) * var(--profile-modal-scale) + ); + --profile-modal-padding-block-end: calc( + (var(--space-lg) - var(--space-sm)) * var(--profile-modal-scale) + ); + --profile-modal-nav-gap: calc(var(--space-xs) * var(--profile-modal-scale)); + } +.profile-modal__content { + display: flex; + flex: 1 1 auto; + flex-direction: column; + block-size: 100%; + min-block-size: 0; + transform: scale(var(--profile-modal-scale)); + transform-origin: top center; + } +.profile-modal__active-profile { + outline: 2px solid transparent; + outline-offset: 2px; +} +.profile-modal__active-profile:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.profile-modal__active-profile { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 1rem; + padding: 1rem; +} +.profile-modal__active-details { + display: flex; + flex: 1 1 var(--profile-modal-active-min-width); + flex-direction: column; + gap: var(--space-2xs); + min-inline-size: 0; + } +.profile-modal__active-meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-xs); + } +.profile-hashtag-list { + display: flex; + flex-wrap: wrap; + gap: var(--space-xs); + margin: 0; + padding: 0; + list-style: none; + } +.profile-hashtag-item { + display: inline-flex; + align-items: center; + gap: var(--space-3xs); + padding-block: var(--space-3xs); + padding-inline: var(--space-sm); + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--color-border-translucent); + background-color: var(--color-panel); + color: var(--color-text); + font-size: var(--font-size-sm); + font-weight: var(--font-weight-medium); + line-height: var(--font-lineheight-tight); + } +.profile-hashtag-remove { + display: inline-flex; + align-items: center; + justify-content: center; + inline-size: var(--space-md); + block-size: var(--space-md); + border-radius: var(--radius-full); + color: var(--color-text-muted); + background: transparent; + border: none; + padding: 0; + cursor: pointer; + } +.profile-hashtag-remove:hover { + color: var(--color-text); + } +.profile-modal__remove-button { + border-width: 2px; +} +.profile-modal__remove-button:focus-visible { + --tw-ring-color: var(--color-critical-strong); + } +.profile-modal__add-profile { + --tw-ring-color: var(--color-ring-alert); + outline: 2px solid transparent; + outline-offset: 2px; + } +.profile-modal__add-profile:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.profile-modal__add-profile { + position: relative; + display: flex; + width: 100%; + align-items: center; + justify-content: flex-start; + gap: 1rem; + border-radius: var(--radius-xl); + padding-left: 1.25rem; + padding-right: 1.25rem; + padding-top: 1rem; + padding-bottom: 1rem; + text-align: left; + color: var(--text-primary); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + border: var(--outline-thick-width) solid var(--color-ring-alert); + background-color: var(--surface-panel-hover); +} +.profile-modal__add-profile:hover { + background-color: color-mix( + in srgb, + var(--surface-panel-hover) 88%, + var(--color-ring-alert) 12% + ); + } +.profile-modal__add-profile:focus-visible { + background-color: color-mix( + in srgb, + var(--surface-panel-hover) 80%, + var(--color-ring-alert) 20% + ); + } +.profile-modal__add-profile-icon { + display: flex; + height: 2.5rem; + width: 2.5rem; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + background-color: color-mix( + in srgb, + var(--color-ring-alert) 18%, + var(--surface-panel) + ); + color: var(--color-ring-alert); +} +.profile-modal__body { + display: flex; + flex: 1 1 auto; + flex-direction: column; + gap: var(--profile-modal-gap); + inline-size: 100%; + min-block-size: 0; + overflow: hidden; + overflow-x: hidden; + padding-block-start: var(--profile-modal-padding-block-start); + padding-block-end: var(--profile-modal-padding-block-end); + padding-inline: var(--profile-modal-padding-inline); + } +.profile-modal__layout { + display: flex; + flex: 1 1 auto; + flex-direction: column; + gap: var(--profile-modal-gap); + inline-size: 100%; + min-block-size: 0; + } +.profile-modal__header { + align-items: center; + } +.profile-modal__header-title { + display: flex; + align-items: center; + gap: var(--space-sm); + } +.profile-modal__menu { + display: flex; + flex-direction: column; + gap: var(--space-sm); + } +.profile-modal__pane-wrapper { + display: flex; + flex: 1 1 auto; + flex-direction: column; + min-block-size: 0; + } +.profile-modal__nav { + display: flex; + flex-wrap: wrap; + gap: var(--profile-modal-nav-gap); + align-self: flex-start; + overflow-x: visible; + } +.profile-nav__unread-dot { + position: absolute; + top: 50%; + left: -6px; + right: auto; + width: var(--space-sm); + height: var(--space-sm); + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--surface-panel); + background-color: var(--status-danger); + display: none; + pointer-events: none; + transform: translateY(-50%); + } +.profile-nav__unread-dot.is-visible { + display: block; + } +.profile-modal__panes { + display: flex; + flex: 1 1 auto; + flex-direction: column; + block-size: 100%; + min-block-size: 0; + overflow-y: auto; + overflow-x: hidden; + padding-inline-end: var(--profile-modal-scrollbar-offset); + scrollbar-gutter: stable; + } +.profile-pane { + display: flex; + flex-direction: column; + min-block-size: auto; + overflow-x: hidden; + } +/* Specific override for messages pane to prevent parent scrolling on desktop */ +@media (min-width: 768px) { + #profilePaneMessages { + height: 100%; + min-height: 0; + overflow: hidden; + } + + #dmAppShellMount { + height: 100%; + min-height: 0; + } + } +.profile-pane.hidden { + display: none !important; + } +@supports not (scrollbar-gutter: stable) { + .profile-modal__panes { + padding-inline-end: calc( + var(--profile-modal-scrollbar-offset) + var(--space-2xs) + ); + } + } +@media (max-width: calc(1024px - var(--breakpoint-edge-offset))) { + .profile-modal__layout[data-mobile-view="menu"] + .profile-modal__pane-wrapper { + display: none; + } + + .profile-modal__layout[data-mobile-view="pane"] .profile-modal__menu { + display: none; + } + } +@media (min-width: 1024px) { + .profile-modal { + max-block-size: var(--modal-shell-max-height); + } + + .profile-modal__body { + gap: calc(var(--profile-modal-gap) + var(--space-2xs)); + padding-inline: calc( + var(--profile-modal-padding-inline) + var(--space-xs) + ); + } + + .profile-modal__layout { + display: grid; + align-items: stretch; + block-size: 100%; + gap: calc(var(--profile-modal-gap) + var(--space-2xs)); + grid-template-columns: + minmax( + var(--profile-modal-nav-min-width), + var(--profile-modal-nav-max-width) + ) + minmax(0, 1fr); + grid-auto-rows: minmax(0, 1fr); + } + + .profile-modal__nav { + flex-direction: column; + flex-wrap: nowrap; + gap: var(--profile-modal-nav-gap); + justify-self: start; + inline-size: var(--profile-modal-nav-max-width); + min-inline-size: var(--profile-modal-nav-min-width); + } + + .profile-modal__pane-wrapper { + block-size: 100%; + } + } +/* Torrent helper classes */ +.beacon-hidden-download, + [data-beacon-hidden-download], + .torrent-download-anchor { + display: none !important; + } +.beacon-clipboard-offscreen, + [data-beacon-clipboard-state="offscreen"], + [data-beacon-clipboard="offscreen"], + .torrent-clipboard-textarea { + position: fixed; + top: 0; + left: var(--offscreen-offset); + opacity: 0; + width: 0; + height: 0; + pointer-events: none; + } +.beacon-toast-motion, + .torrent-toast-motion { + transition-property: opacity, transform; + will-change: opacity, transform; + opacity: 0; + transform: translateY(var(--toast-translate)); + } +.beacon-toast-motion[data-beacon-motion="enter"], + .beacon-toast-motion[data-beacon-motion="show"], + .torrent-toast-motion[data-beacon-motion="enter"], + .torrent-toast-motion[data-beacon-motion="show"] { + opacity: 1; + transform: translateY(0); + } +.beacon-toast-motion[data-beacon-motion="exit"], + .torrent-toast-motion[data-beacon-motion="exit"] { + opacity: 0; + transform: translateY(var(--toast-translate)); + } +.torrent-toast { + pointer-events: auto; + width: 100%; + max-width: 28rem; + border-radius: var(--radius-lg); + padding-left: 1rem; + padding-right: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.75rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 500; + letter-spacing: -0.025em; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-inset: inset; +} +.torrent-toast--info { + border-width: 1px; + border-color: var(--border-overlay); + background-color: var(--surface-base); + color: var(--text-primary); +} +.torrent-toast--success { + border-width: 1px; + border-color: var(--color-info); + --tw-border-opacity: 0.6; + background-color: var(--color-info); + color: var(--color-white); +} +.torrent-toast--error { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.6; + background-color: var(--color-critical); + color: var(--color-white); +} +.torrent-toast--warn { + border-width: 1px; + border-color: var(--status-warning-strong); + --tw-border-opacity: 0.7; + background-color: var(--status-warning-strong); + color: var(--status-warning-strong); +} +.watch-history-card { + min-width: 0; + --video-card-lift-translate-y: 0; + --video-card-backdrop-opacity: 0; + --video-card-backdrop-translate-y: var(--space-md-plus); + --video-card-backdrop-scale: 1.08; + --video-card-backdrop-blur: var(--blur-thumbnail-blur); + outline: 2px solid transparent; + outline-offset: 2px; + } +.watch-history-card:focus-visible { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); + --tw-ring-opacity: 0.7; + --tw-ring-offset-width: 2px; + --tw-ring-offset-color: var(--surface-base); + transition-property: box-shadow; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-fast); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + --tw-ring-color: var(--color-accent); +} +.watch-history-card { + position: relative; + border-radius: var(--radius-lg); + border-width: 1px; + border-color: transparent; + background-color: var(--surface-raised); + color: var(--text-primary); + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transform: translate3d(0, var(--video-card-lift-translate-y), 0); + transition-property: + transform, box-shadow, border-color, background-color, color; + will-change: transform; + isolation: isolate; +} +.watch-history-card::before { + content: ""; + position: absolute; + inset: 0; + z-index: 0; + opacity: var(--video-card-backdrop-opacity); + background-image: var(--video-card-thumb-url, none); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + transform: translate3d(0, var(--video-card-backdrop-translate-y), 0) + scale(var(--video-card-backdrop-scale)); + filter: blur(var(--video-card-backdrop-blur)); + transition: + opacity var(--motion-duration-base) var(--motion-ease-in-out), + transform var(--motion-duration-base) var(--motion-ease-in-out), + filter var(--motion-duration-base) var(--motion-ease-in-out); + pointer-events: none; + will-change: opacity, transform, filter; + } +.watch-history-card > * { + position: relative; + z-index: 1; + } +.watch-history-card:hover,.watch-history-card:focus-within { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } +.watch-history-card:focus-visible { + border-color: var(--color-accent); + --tw-border-opacity: 0.4; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.watch-history-card[data-state="critical"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +.watch-history-card[data-state="private"] { + background-color: var(--surface-raised-private); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.watch-history-card[data-state="disabled"] { + opacity: 0.6; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.watch-history-card[data-alert="nsfw-owner"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--color-black); +} +.watch-history-card[data-alert="nsfw-owner"]:hover { + --tw-border-opacity: 0.6; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.watch-history-card img[data-thumbnail-state="blurred"],.watch-history-card img[data-visual-state="blurred"] { + transition-duration: var(--motion-duration-base); + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + filter: blur(var(--blur-thumbnail-blur)); + transform: scale(1.05); +} +.watch-history-card[data-owner-is-viewer="true"][data-url-health-state="offline"][data-stream-health-state="unhealthy"] { + border-width: 1px; + border-color: var(--color-critical); + --tw-border-opacity: 0.4; + background-color: var(--surface-raised-critical); +} +#playerModal + .player-modal__module-item + > .watch-history-card:not(.player-modal__similar-card) { + display: flex; + width: 100%; + flex-direction: row; + flex-wrap: nowrap; + align-items: stretch; + gap: var(--space-md); +} +#playerModal + .player-modal__module-item + > .watch-history-card:not(.player-modal__similar-card) + .video-card__media { + width: clamp( + var(--video-modal-item-media-min), + 18vw, + var(--video-modal-item-media-max) + ); + flex-shrink: 0; + overflow: hidden; + border-radius: var(--radius-lg); + } +#playerModal + .player-modal__module-item + > .watch-history-card:not(.player-modal__similar-card) + .video-card__content { + padding: clamp(var(--space-sm), 1.25vw, var(--space-md)); + display: flex; + min-width: 0px; + flex: 1 1 0%; + flex-direction: column; + gap: var(--space-sm); + } +#playerModal + .player-modal__module-item + > .watch-history-card:not(.player-modal__similar-card) + .video-card__meta { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); + color: var(--text-muted-strong); +} +.watch-history-card[data-motion="enter"] { + opacity: 0; + animation: card-motion-enter 220ms ease-out forwards; + } +@media (min-width: 1024px) { + .watch-history-card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + } +@media (max-width: calc(1024px - var(--breakpoint-edge-offset))) { + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .watch-history-card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .watch-history-card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .watch-history-card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + } +.watch-history-card { + display: flex; + flex-wrap: wrap; + align-items: stretch; + gap: 1.25rem; + padding: 1rem; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +@media (prefers-reduced-motion: reduce) { + + .watch-history-card,.watch-history-card[data-motion="enter"] { + transition-property: none; + } + + .watch-history-card[data-motion="enter"] { + opacity: 1; + animation: none; + } +} +.watch-history-card:hover { + --tw-translate-y: -0.125rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +@media (min-width: 640px) { + .watch-history-card { + gap: 1.5rem; + padding: 1.25rem; + } +} +.watch-history-card [data-thumbnail-state="blurred"] img, + .watch-history-card [data-visual-state="blurred"] img { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + filter: blur(var(--blur-thumbnail-blur)); + transform: scale(1.05); +} +.watch-history-card__hidden { + margin-top: var(--space-md); + border-radius: var(--radius-lg); + border-width: 1px; + border-style: dashed; + border-color: var(--border-default); + background-color: var(--surface-overlay-panel-soft); + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + color: var(--text-primary); +} +.watch-history-card__hidden .moderation-badge { + align-self: flex-start; +} +/* Ensure the video modal avatar respects the blur state */ +#playerModal .channel-card__avatar img[data-visual-state="blurred"] { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + filter: blur(var(--blur-thumbnail-blur)); + transform: scale(1.05); +} +/* Override moderation badge text color inside the modal bar for better contrast in all themes */ +#playerModal .video-modal__moderation-bar .moderation-badge { + --text-status-neutral-on: var(--color-text); + --text-status-warning-on: var(--color-warning-on); + } +#playerModal + .video-modal__moderation-bar + .moderation-badge[data-variant="neutral"] { + color: var(--color-text); + } +.\!container { + max-width: var(--layout-docs-max-width) !important; + margin: 0 auto !important; + padding: var(--space-md) !important; + } +.container { + max-width: var(--layout-docs-max-width); + margin: 0 auto; + padding: var(--space-md); + } +.qr-code__table { + border: 0; + border-collapse: collapse; + margin: var(--qr-code-table-margin, 0); + } +.qr-code__cell { + border: 0; + border-collapse: collapse; + padding: 0; + margin: 0; + width: var(--qr-code-cell-width); + height: var(--qr-code-cell-height); + background-color: var(--qr-code-color-light); + } +.qr-code__cell--dark { + background-color: var(--qr-code-color-dark); + } +.qr-code__container[data-qr-code-mode="image"] .qr-code__canvas { + display: none; + } +.qr-code__container[data-qr-code-mode="image"] .qr-code__image { + display: block; + } +.qr-code__container[data-qr-code-mode="canvas"] .qr-code__canvas { + display: block; + } +.qr-code__container[data-qr-code-mode="canvas"] .qr-code__image { + display: none; + } +.fade-in { + opacity: 0; + animation: interface-fade-in 280ms ease-out forwards; + animation-delay: var(--fade-in-delay, 0ms); + } +.fade-in-delay-100 { + --fade-in-delay: 100ms; + } +.fade-in-delay-200 { + --fade-in-delay: 200ms; + } +.fade-in-delay-300 { + --fade-in-delay: 300ms; + } +.\!card[data-motion="enter"] { + opacity: 0 !important; + animation: card-motion-enter 220ms ease-out forwards !important; + } +.card[data-motion="enter"] { + opacity: 0; + animation: card-motion-enter 220ms ease-out forwards; + } +.icon-button { + display: inline-flex; + align-items: center; + justify-content: center; + width: var(--icon-size-lg); + height: var(--icon-size-lg); + min-width: var(--icon-size-lg); + min-height: var(--icon-size-lg); + flex: 0 0 var(--icon-size-lg); + line-height: 0; + background-color: var(--color-neutral-700); + color: var(--color-white); + border: none; + border-radius: var(--radius-full); + cursor: pointer; + transition: + background-color 200ms ease, + box-shadow 200ms ease; + } +.icon-button:hover { + background-color: var(--color-neutral-600); + } +.icon-button:focus, + .icon-button:active { + outline: none; + box-shadow: 0 0 0 var(--icon-button-ring-width) var(--color-ring-alert); + } +.icon-image { + width: var(--icon-size-md); + height: var(--icon-size-md); + pointer-events: none; + } +.accent-action-button, + .channel-action-button { + --accent-action-bg: color-mix( + in srgb, + var(--surface-overlay-panel) 78%, + transparent + ); + --accent-action-border: color-mix( + in srgb, + var(--border-overlay) 92%, + transparent + ); + --accent-action-bg-hover: color-mix( + in srgb, + var(--color-accent) 22%, + var(--surface-overlay-panel) + ); + --accent-action-ring: color-mix( + in srgb, + var(--color-accent) 48%, + transparent + ); + --accent-action-bg-active: color-mix( + in srgb, + var(--color-accent-pressed) 28%, + var(--surface-overlay-panel) + ); + + color: var(--color-text); + background-color: var(--accent-action-bg); + border-color: var(--accent-action-border); + border-style: solid; + border-width: var(--border-width-hairline); + } +.accent-action-button:hover, + .accent-action-button:focus-visible, + .channel-action-button:hover, + .channel-action-button:focus-visible { + color: var(--color-accent-strong); + background-color: var(--accent-action-bg-hover); + } +.accent-action-button:focus, + .accent-action-button:focus-visible, + .channel-action-button:focus, + .channel-action-button:focus-visible { + box-shadow: 0 0 0 var(--icon-button-ring-width) var(--accent-action-ring); + } +.accent-action-button:active, + .channel-action-button:active { + color: var(--color-accent-pressed); + background-color: var(--accent-action-bg-active); + } +.modal-nav .icon-button { + box-shadow: none; + padding: 0; + gap: 0; + width: var(--icon-size-lg); + height: var(--icon-size-lg); + min-width: var(--icon-size-lg); + min-height: var(--icon-size-lg); + } +.modal-nav + .icon-button:not(.accent-action-button):not(.channel-action-button) { + border: none; + } +.modal-meta { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + } +.modal-view-count { + display: inline-flex; + align-items: center; + gap: var(--space-2xs); + font-size: var(--font-size-sm); + line-height: var(--space-md-plus); + color: var(--color-muted-alt); + white-space: nowrap; + } +.view-count-text { + white-space: nowrap; + color: var(--color-muted-strong); + } +.ratio-16-9 { + position: relative; + width: 100%; + padding-top: 56.25%; + background-color: var(--color-card); + } +.ratio-16-9 > img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + } +#modalContainer { + position: fixed; + inset: 0; + z-index: var(--z-modal-root); + pointer-events: none; + isolation: isolate; + } +#modalContainer > * { + pointer-events: auto; + } +#modalContainer > [id$="Modal"]:not(#playerModal) { + z-index: var(--z-modal-root); + } +#modalContainer > [id$="Modal"]:not(#playerModal) > .bv-modal-backdrop { + z-index: var(--z-modal-overlay); + } +#modalContainer > [id$="Modal"]:not(#playerModal) .bv-modal__panel { + z-index: var(--z-modal-content); + } +#modalContainer > #profileModal, + #profileModal[data-modal-stack="top"] { + z-index: var(--z-modal-top-root); + } +#modalContainer > #profileModal > .bv-modal-backdrop, + #profileModal[data-modal-stack="top"] > .bv-modal-backdrop { + z-index: var(--z-modal-top-overlay); + } +#modalContainer > #profileModal .bv-modal__panel, + #profileModal[data-modal-stack="top"] .bv-modal__panel { + z-index: var(--z-modal-top-content); + } +#modalContainer > #eventDetailsModal { + z-index: var(--z-modal-top-root); + } +#modalContainer > #eventDetailsModal > .bv-modal-backdrop { + z-index: var(--z-modal-top-overlay); + } +#modalContainer > #eventDetailsModal .bv-modal__panel { + z-index: var(--z-modal-top-content); + } +#shareNostrModal { + z-index: var(--z-modal-peak-root) !important; + } +#shareNostrModal > .bv-modal-backdrop { + z-index: var(--z-modal-peak-overlay) !important; + } +#shareNostrModal .bv-modal__panel { + z-index: var(--z-modal-peak-content) !important; + } +.bv-modal[data-nested-modal-active="true"] { + pointer-events: none; + visibility: hidden; + } +#modalContainer > #loginModal { + z-index: var(--z-modal-peak-root); + } +#modalContainer > #loginModal > .bv-modal-backdrop { + z-index: var(--z-modal-peak-overlay); + } +#modalContainer > #loginModal .bv-modal__panel { + z-index: var(--z-modal-peak-content); + } +#modalContainer > #playerModal { + z-index: var(--z-modal-player); + } +#modalContainer > #playerModal .player-modal__container, + #modalContainer > #playerModal .player-modal__content { + z-index: var(--z-modal-content); + } +.modal-always-on-top { + z-index: var(--z-modal-always-top) !important; + } +#playerModal { + position: fixed; + inset: 0; + z-index: var(--z-modal-player); + flex-direction: column; + align-items: stretch; + justify-content: flex-start; + width: 100vw; + height: 100vh; + padding: 0; + background-color: var(--color-surface); + color: var(--color-subtle-text); + --player-modal-inline-max: var(--layout-player-max-width); + --player-modal-inline-padding: clamp( + var(--space-md-plus), + 4vw, + var(--space-2xl) + ); + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior: contain; + -webkit-overflow-scrolling: touch; + } +#modalVideo { + width: 100%; + aspect-ratio: 16 / 9; + background-color: var(--color-black); + } +.notification-portal { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: var(--z-overlay-toast); + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-md); + padding: calc(var(--space-xl) + env(safe-area-inset-top)) var(--space-lg) + var(--space-lg); + pointer-events: none; + opacity: 0; + transform: translateY(var(--toast-translate)); + transition: + transform var(--motion-duration-base) var(--motion-ease-out), + opacity var(--motion-duration-base) var(--motion-ease-out); + } +@media (min-width: 640px) { + .notification-portal { + padding-inline: var(--space-xl); + } + } +.notification-portal:has(.notification-banner:not(.hidden)) { + opacity: 1; + transform: translateY(0); + } +.notification-portal--active { + opacity: 1; + transform: translateY(0); + } +.notification-banner, + .torrent-toast { + --notify-accent: var(--notification-banner-accent); + --notify-accent-strong: var(--notification-banner-accent-strong); + --notify-border: var(--notification-banner-border); + --notify-background: var(--notification-banner-background); + --notify-foreground: var(--notification-banner-text); + + position: relative; + display: flex; + align-items: center; + gap: var(--space-md); + width: min(var(--notification-banner-max-inline), 100%); + padding: var(--space-md) var(--space-xl); + border-radius: var(--radius-xl); + border: var(--border-width-hairline) solid var(--notify-border); + background: var(--notify-background); + color: var(--notify-foreground); + box-shadow: 0 var(--shadow-notification-offset-y) + var(--shadow-notification-blur) var(--color-shadow-notification); + backdrop-filter: blur(var(--overlay-backdrop-blur)); + pointer-events: auto; + isolation: isolate; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + font-weight: 600; + line-height: 1.375; + transition: + transform var(--motion-duration-base) var(--motion-ease-out), + opacity var(--motion-duration-base) var(--motion-ease-out); + } +.notification-banner::before, + .torrent-toast::before { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + background: linear-gradient( + 135deg, + var(--notify-accent) 0%, + var(--notify-accent-strong) 100% + ); + opacity: 0.18; + pointer-events: none; + } +.notification-banner > *, + .torrent-toast > * { + position: relative; + z-index: 1; + } +.notification-dismiss { + display: inline-flex; + height: 2rem; + width: 2rem; + align-items: center; + justify-content: center; + border-radius: var(--radius-full); + border-width: 1px; + border-color: transparent; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; + transition-duration: var(--motion-duration-base); + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); + color: inherit; + opacity: 0.75; + background-color: var(--notify-dismiss-background); +} +.notification-dismiss:hover, + .notification-dismiss:focus-visible { + opacity: 1; + background-color: var(--notify-dismiss-background-hover); + } +.notification-dismiss svg { + height: 1rem; + width: 1rem; +} +.notification-banner:not(.hidden) { + animation: notification-slide-in var(--motion-duration-base) + var(--motion-ease-out); + } +.notification-banner--critical, + .torrent-toast--error { + --notify-accent: var(--notification-banner-critical-accent); + --notify-accent-strong: var(--notification-banner-critical-accent-strong); + --notify-border: var(--notification-banner-critical-border); + --notify-background: var(--notification-banner-critical-background); + --notify-foreground: var(--notification-banner-critical-text); + } +.notification-banner--success, + .torrent-toast--success { + --notify-accent: var(--notification-banner-success-accent); + --notify-accent-strong: var(--notification-banner-success-accent-strong); + --notify-border: var(--notification-banner-success-border); + --notify-background: var(--notification-banner-success-background); + --notify-foreground: var(--notification-banner-success-text); + } +.notification-banner--info, + .torrent-toast--info { + --notify-accent: var(--notification-banner-info-accent); + --notify-accent-strong: var(--notification-banner-info-accent-strong); + --notify-border: var(--notification-banner-info-border); + --notify-background: var(--notification-banner-info-background); + --notify-foreground: var(--notification-banner-info-text); + } +.notification-banner--warning, + .torrent-toast--warn { + --notify-accent: var(--notification-banner-warning-accent); + --notify-accent-strong: var(--notification-banner-warning-accent-strong); + --notify-border: var(--notification-banner-warning-border); + --notify-background: var(--notification-banner-warning-background); + --notify-foreground: var(--notification-banner-warning-text); + } +.status-banner .status-spinner { + animation: spin 1s linear infinite; + border: var(--space-3xs) solid var(--color-info-border); + border-radius: var(--radius-full); + border-top-color: var(--color-info); + flex-shrink: 0; + height: var(--icon-size-md); + width: var(--icon-size-md); + } +.status-banner .status-message { + flex: 1 1 auto; + } +@keyframes notification-slide-in { + from { + opacity: 0; + transform: translateY(var(--toast-translate)); + } + + to { + opacity: 1; + transform: translateY(0); + } + } +.status-spinner--inline { + animation: spin 1s linear infinite; + border: var(--space-3xs) solid var(--color-border-info-soft); + border-radius: var(--radius-full); + border-top-color: var(--color-info); + display: inline-block; + height: var(--space-md); + width: var(--space-md); + } +body.iframe-form { + background-color: transparent; + color: var(--color-text); + font-family: var(--font-family-sans); + margin: var(--space-lg); + } +body.iframe-form .container { + width: 100%; + max-width: 100%; + margin: 0; + padding: 0; + } +body.iframe-form .\!container { + width: 100% !important; + max-width: 100% !important; + margin: 0 !important; + padding: 0 !important; + } +body.iframe-form .form-container { + background-color: var(--color-surface-alt); + border-radius: var(--radius-md); + box-shadow: var(--shadow-md); + color: var(--color-text); + display: flex; + flex-direction: column; + gap: var(--space-md); + padding: var(--space-lg); + } +body.iframe-form .form-container > p { + margin: 0; + } +body.iframe-form form { + display: flex; + flex-direction: column; + } +body.iframe-form form > * + * { + margin-top: var(--space-sm); + } +body.iframe-form form h1, + body.iframe-form form h2 { + color: var(--color-text); + margin-top: var(--space-md); + } +body.iframe-form label { + color: var(--color-subtle-text); + display: block; + font-weight: 600; + margin-top: var(--space-sm); + } +body.iframe-form label + .form-control, + body.iframe-form label + .textarea, + body.iframe-form label + .select { + margin-top: var(--space-xs); + } +body.iframe-form .checkbox-group, + body.iframe-form .radio-group { + display: flex; + flex-wrap: wrap; + gap: var(--space-sm); + margin-top: var(--space-xs); + } +body.iframe-form .checkbox-group label, + body.iframe-form .radio-group label { + align-items: center; + color: var(--color-subtle-text); + display: inline-flex; + font-weight: 500; + gap: var(--space-xs); + margin: 0; + } +body.iframe-form .checkbox-group input[type="checkbox"], + body.iframe-form .radio-group input[type="radio"] { + margin: 0; + } +body.iframe-form .radio-group input[type="radio"] { + accent-color: var(--color-accent-strong); + } +body.iframe-form button.btn { + align-self: flex-start; + margin-top: var(--space-md); + } +body.iframe-form button.\!btn { + align-self: flex-start !important; + margin-top: var(--space-md) !important; + } +body.iframe-form #status { + background: var(--color-surface); + border-radius: var(--radius-sm); + box-shadow: inset 0 0 0 var(--border-width-hairline) + var(--color-border-translucent); + color: var(--color-subtle-text); + min-height: calc(var(--space-2xl) + var(--space-xl)); + padding: var(--space-sm); + white-space: pre-wrap; + } +body.iframe-form .status-line { + color: var(--color-subtle-text); + margin: var(--space-2xs) 0; + } +body.iframe-form .status-line.error { + color: var(--color-critical-strong); + } +body.iframe-form .status-line.\!error { + color: var(--color-critical-strong) !important; + } +body.iframe-form .status-line.success { + color: var(--color-info-strong); + } +body.iframe-form .status-line.\!success { + color: var(--color-info-strong) !important; + } +body.iframe-form .status-line.warn { + color: var(--color-warning-strong); + } +@media (max-width: 640px) { + body.iframe-form { + margin: var(--space-md); + } + + body.iframe-form .form-container { + padding: var(--space-md); + } + } +#sidebarContainer { + position: relative; + overflow: visible; + } +#sidebar { + position: fixed; + top: 0; + left: 0; + width: var(--sidebar-width); + min-width: var(--sidebar-width); + height: 100vh; + height: 100dvh; + color: var(--color-text-frosted-strong); + overflow-x: hidden; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + overscroll-behavior: contain; + overscroll-behavior-inline: contain; + touch-action: pan-y; + scrollbar-gutter: stable both-edges; + background: transparent; + border-right: none; + backdrop-filter: none; + -webkit-backdrop-filter: none; + transition: + width 200ms ease, + transform 300ms ease; + z-index: var(--z-sidebar); + box-shadow: none; + isolation: isolate; + } +body.sidebar-collapsed, + #sidebar.sidebar-collapsed, + #sidebar[data-state="collapsed"], + #app.sidebar-collapsed { + --sidebar-width: var(--sidebar-width-collapsed); + } +body.sidebar-expanded, + #sidebar.sidebar-expanded, + #sidebar[data-state="expanded"], + #app.sidebar-expanded { + --sidebar-width: var(--sidebar-width-expanded); + } +#sidebar .sidebar__inner { + display: flex; + flex-direction: column; + height: 100%; + padding-block-start: max( + var(--space-sidebar-shell-block-start), + calc(var(--app-header-centerline) - (var(--sidebar-control-size) / 2)) + ); + padding-block-end: var(--space-sidebar-shell-block-end); + padding-inline: var(--space-sidebar-shell-inline); + width: 100%; + border-radius: var(--radius-sidebar-shell); + border: none; + background: none; + box-shadow: none; + backdrop-filter: none; + -webkit-backdrop-filter: none; + overflow: visible; + isolation: isolate; + transition: color 200ms ease; + } +.sidebar-scroll { + display: flex; + flex-direction: column; + gap: var(--space-sidebar-scroll-gap); + width: 100%; + height: 100%; + min-height: 0; + flex: 1 1 auto; + overflow: visible; + } +.sidebar-panel { + position: relative; + width: 100%; + display: flex; + flex-direction: column; + gap: var(--space-sidebar-panel-gap); + padding: var(--space-sidebar-panel-padding-block) + var(--space-sidebar-panel-padding-inline); + border-radius: var(--radius-sidebar-panel); + border: none; + background: transparent; + box-shadow: none; + color: inherit; + backdrop-filter: none; + -webkit-backdrop-filter: none; + overflow: hidden; + isolation: isolate; + transition: + border-color 200ms ease, + box-shadow 220ms ease, + background 220ms ease; + } +.sidebar-panel--primary { + flex: 1 1 auto; + min-height: 0; + padding-block-start: 0; + } +.sidebar-panel__header { + display: flex; + justify-content: flex-end; + margin-bottom: var(--space-md); + } +.sidebar-collapse-toggle { + display: inline-flex; + align-items: center; + justify-content: center; + width: var(--sidebar-control-size); + height: var(--sidebar-control-size); + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid + var(--color-border-translucent-medium); + background: var(--color-surface-tint-subtle); + color: inherit; + cursor: pointer; + transition: + background 180ms ease, + color 180ms ease, + border-color 180ms ease; + flex-shrink: 0; + box-sizing: border-box; + } +.sidebar-collapse-toggle:hover { + background: var(--color-border-translucent); + border-color: var(--color-border-translucent-stronger); + color: var(--color-text); + } +.sidebar-collapse-toggle:focus-visible { + outline: var(--space-3xs) solid var(--color-secondary); + outline-offset: var(--space-2xs); + } +.sidebar-collapse-toggle__icon { + width: var(--icon-size-sm); + height: var(--icon-size-sm); + transition: transform 200ms ease; + } +.sidebar-nav { + display: flex; + flex-direction: column; + gap: var(--space-xs); + opacity: 1; + transition: opacity 160ms ease; + width: 100%; + } +.sidebar-nav-link { + --sidebar-nav-translate-x: 0; + --sidebar-nav-link-highlight-opacity: 0; + --sidebar-nav-link-highlight-scale: 0.96; + display: flex; + align-items: center; + gap: var(--space-sidebar-footer-gap); + padding-block: var(--space-sidebar-nav-padding-block); + padding-inline-start: var(--space-sidebar-nav-padding-inline-start); + padding-inline-end: var(--space-sidebar-nav-padding-inline-end); + min-height: var(--sidebar-control-size); + border-radius: var(--radius-sidebar-nav); + font-size: var(--font-size-sidebar-nav); + font-weight: 600; + letter-spacing: 0.015em; + color: var(--color-text); + text-decoration: none; + width: 100%; + position: relative; + border: var(--border-width-hairline) solid transparent; + background: none; + box-shadow: none; + transform: translateX(var(--sidebar-nav-translate-x)); + transition: + color 180ms ease, + border-color 200ms ease, + box-shadow 220ms ease, + transform 220ms ease; + overflow: hidden; + isolation: isolate; + backdrop-filter: none; + -webkit-backdrop-filter: none; + } +.sidebar-nav-link::before, + .sidebar-nav-link::after { + content: ""; + position: absolute; + inset: calc(var(--border-width-hairline) * -1); + border-radius: inherit; + pointer-events: none; + transition: + opacity 220ms ease, + transform 240ms ease; + z-index: -1; + } +.sidebar-nav-link::before { + background: linear-gradient( + 120deg, + var(--color-sidebar-accent-start) 0%, + var(--color-sidebar-accent-end) 100% + ); + opacity: var(--sidebar-nav-link-highlight-opacity); + transform: scale(var(--sidebar-nav-link-highlight-scale)); + filter: saturate(140%); + } +.sidebar-nav-link::after { + background: linear-gradient( + 105deg, + var(--color-sidebar-hover) 0%, + transparent 75% + ); + opacity: 0.22; + mix-blend-mode: screen; + z-index: -2; + } +.sidebar-nav-link:hover, + .sidebar-nav-link:focus-visible { + --sidebar-nav-link-highlight-opacity: 1; + --sidebar-nav-link-highlight-scale: 1.02; + --sidebar-nav-translate-x: var(--space-sidebar-nav-translate); + color: var(--color-white); + border-color: var(--color-sidebar-hover-strong); + box-shadow: + 0 0 0 var(--border-width-hairline) var(--color-sidebar-hover-strong), + var(--shadow-sidebar-accent); + } +.sidebar-nav-link:focus-visible { + outline: none; + box-shadow: var(--shadow-sidebar-focus-ring), var(--shadow-sidebar-accent); + } +.sidebar-nav-link:hover::after, + .sidebar-nav-link:focus-visible::after { + opacity: 0.35; + } +.sidebar-nav-link--sub { + font-size: var(--font-size-sidebar-subnav); + font-weight: 500; + color: var(--color-sidebar-text-muted); + padding-block: var(--space-sidebar-subnav-padding-block); + letter-spacing: 0.02em; + --sidebar-nav-link-highlight-opacity: 0.25; + --sidebar-nav-link-highlight-scale: 1; + } +.sidebar-icon { + width: var(--space-lg); + height: var(--space-lg); + min-width: var(--space-lg); + min-height: var(--space-lg); + flex-shrink: 0; + display: block; + filter: var(--sidebar-icon-filter); + transition: filter 180ms ease; + } +.sidebar-footer { + display: flex; + flex-direction: column; + gap: var(--space-sidebar-footer-gap); + margin-top: auto; + position: relative; + z-index: 2; + } +.sidebar-dropup-trigger { + position: relative; + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--space-sidebar-footer-gap); + width: 100%; + padding-block: var(--space-sidebar-trigger-padding-block); + padding-inline-start: var(--space-sidebar-nav-padding-inline-start); + padding-inline-end: var(--space-sidebar-nav-padding-inline-end); + min-height: var(--sidebar-control-size); + border-radius: var(--radius-sidebar-nav); + border: var(--border-width-hairline) solid transparent; + background: none; + color: var(--color-text); + font-size: var(--font-size-sidebar-trigger); + font-weight: 600; + cursor: pointer; + box-sizing: border-box; + flex-shrink: 0; + overflow: hidden; + isolation: isolate; + backdrop-filter: none; + -webkit-backdrop-filter: none; + box-shadow: none; + transition: + border-color 200ms ease, + color 200ms ease, + box-shadow 220ms ease; + } +.sidebar-dropup-trigger::before { + content: ""; + position: absolute; + inset: calc(var(--border-width-hairline) * -1); + border-radius: inherit; + pointer-events: none; + background: linear-gradient( + 120deg, + var(--color-sidebar-accent-start) 0%, + var(--color-sidebar-accent-end) 100% + ); + opacity: 0; + transform: scale(0.96); + transition: + opacity 200ms ease, + transform 220ms ease; + z-index: -1; + filter: saturate(140%); + } +.sidebar-dropup-trigger::after { + content: ""; + position: absolute; + inset: calc(var(--border-width-hairline) * -1); + border-radius: inherit; + pointer-events: none; + background: linear-gradient( + 110deg, + var(--color-sidebar-hover) 0%, + transparent 80% + ); + opacity: 0.18; + mix-blend-mode: screen; + transition: opacity 200ms ease; + z-index: -2; + } +.sidebar-dropup-trigger:hover, + .sidebar-dropup-trigger:focus-visible { + color: var(--color-white); + border-color: var(--color-sidebar-hover-strong); + box-shadow: + 0 0 0 var(--border-width-hairline) var(--color-sidebar-hover-strong), + var(--shadow-sidebar-dropup); + } +.sidebar-dropup-trigger:hover::before, + .sidebar-dropup-trigger:focus-visible::before { + opacity: 1; + transform: scale(1.02); + } +.sidebar-dropup-trigger:hover::after, + .sidebar-dropup-trigger:focus-visible::after { + opacity: 0.35; + } +.sidebar-dropup-trigger:focus-visible { + outline: none; + box-shadow: var(--shadow-sidebar-focus-ring), var(--shadow-sidebar-dropup); + } +.sidebar-dropup-trigger__glyph { + width: var(--icon-size-md); + height: var(--icon-size-md); + opacity: 0.9; + } +.sidebar-dropup-trigger__chevron { + width: var(--icon-size-sm); + height: var(--icon-size-sm); + transition: transform 180ms ease; + } +.sidebar-dropup-trigger__chevron.is-rotated, + .sidebar-dropup-trigger[aria-expanded="true"] + .sidebar-dropup-trigger__chevron { + transform: rotate(180deg); + } +.sidebar-dropup-panel { + position: absolute; + left: 0; + right: 0; + bottom: calc(100% + var(--space-sidebar-popover-offset)); + border-radius: var(--radius-xl); + border: var(--border-width-hairline) solid + var(--color-sidebar-border-strong); + background: linear-gradient( + 160deg, + color-mix(in srgb, var(--color-sidebar-surface) 88%, transparent) 0%, + color-mix(in srgb, var(--color-sidebar-surface-alt) 68%, transparent) 100% + ); + box-shadow: + inset 0 0 0 var(--border-width-fine) var(--color-sidebar-border), + var(--shadow-sidebar-panel); + padding: var(--space-sidebar-popover-padding-block) + var(--space-sidebar-popover-padding-inline); + color: var(--color-text-frosted); + opacity: 0; + visibility: hidden; + pointer-events: none; + transform: translateY(var(--space-sm)); + transition: + opacity 180ms ease, + transform 180ms ease, + visibility 180ms ease, + box-shadow 220ms ease; + backdrop-filter: blur(var(--sidebar-panel-backdrop-blur)) + saturate(var(--sidebar-panel-backdrop-saturation)); + -webkit-backdrop-filter: blur(var(--sidebar-panel-backdrop-blur)) + saturate(var(--sidebar-panel-backdrop-saturation)); + z-index: 5; + isolation: isolate; + } +.sidebar-dropup-panel[data-state="expanded"] { + opacity: 1; + visibility: visible; + pointer-events: auto; + transform: translateY(0); + } +.sidebar-dropup-panel__inner { + display: flex; + flex-direction: column; + gap: var(--space-sidebar-popover-gap); + width: 100%; + padding-inline-end: var(--space-sidebar-dropup-scroll-reserve); + max-height: var(--sidebar-dropup-max-height); + overflow-y: auto; + overflow-x: hidden; + scrollbar-gutter: stable both-edges; + } +.sidebar-dropup-panel__inner.is-measuring { + position: absolute; + width: -moz-max-content; + width: max-content; + max-width: none; + visibility: hidden; + pointer-events: none; + left: var(--offscreen-offset); + right: auto; + top: auto; + bottom: auto; + } +.sidebar-dropup-measure { + position: absolute; + visibility: hidden; + pointer-events: none; + height: 0; + overflow: hidden; + } +.sidebar-dropup-panel__inner > * { + width: 100%; + min-width: 0; + } +#sidebar[data-footer-state="expanded"] .sidebar-nav { + opacity: 0; + pointer-events: none; + } +#sidebar[data-footer-state="collapsed"] .sidebar-nav { + opacity: 1; + } +.sidebar-loading-wrapper { + display: flex; + justify-content: center; + align-items: center; + padding: var(--space-2xl) 0; + width: 100%; + grid-column: 1 / -1; + } +.sidebar-loading-indicator { + display: inline-flex; + align-items: center; + gap: var(--space-sm); + color: var(--color-muted-strong); + font-size: var(--font-size-sm); + font-weight: 500; + letter-spacing: 0.01em; + } +.sidebar-loading-text { + white-space: nowrap; + } +#app { + box-sizing: border-box; + transition: + margin-left 200ms ease, + width 200ms ease, + max-width 200ms ease; + } +#app[data-sidebar-state="collapsed"] { + margin-left: calc( + var(--sidebar-width-collapsed) + var(--sidebar-content-gap) + ); + width: calc( + 100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap) + ); + max-width: calc( + 100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap) + ); + } +#app[data-sidebar-state="expanded"] { + margin-left: calc( + var(--sidebar-width-expanded) + var(--sidebar-content-gap) + ); + width: calc( + 100vw - var(--sidebar-width-expanded) - var(--sidebar-content-gap) + ); + max-width: calc( + 100vw - var(--sidebar-width-expanded) - var(--sidebar-content-gap) + ); + } +body.sidebar-collapsed #sidebar .sidebar-nav-link, + #sidebar.sidebar-collapsed .sidebar-nav-link { + justify-content: center; + width: var(--sidebar-control-size); + padding: 0; + margin-inline: auto; + border-radius: var(--radius-full); + --sidebar-nav-translate-x: 0; + --sidebar-nav-link-highlight-scale: 1; + } +body.sidebar-expanded #sidebar .sidebar-nav-link, + #sidebar.sidebar-expanded .sidebar-nav-link { + justify-content: flex-start; + } +body.sidebar-collapsed #sidebar .sidebar-text, + #sidebar.sidebar-collapsed .sidebar-text { + display: none; + } +body.sidebar-collapsed #sidebar .sidebar__inner, + #sidebar.sidebar-collapsed .sidebar__inner { + padding-inline: var(--space-2xs); + } +body.sidebar-collapsed #sidebar .sidebar-panel, + #sidebar.sidebar-collapsed .sidebar-panel { + padding-inline: calc(var(--space-3xs) * 3); + } +body.sidebar-collapsed #sidebar .sidebar-panel__header, + #sidebar.sidebar-collapsed .sidebar-panel__header { + justify-content: center; + } +body.sidebar-collapsed #sidebar .sidebar-collapse-toggle, + #sidebar.sidebar-collapsed .sidebar-collapse-toggle { + margin-inline: auto; + } +#sidebar .sidebar-toggle-icon--rotated { + transform: rotate(180deg); + } +body.sidebar-collapsed #sidebar .sidebar-toggle-icon--rotated, + #sidebar.sidebar-collapsed .sidebar-toggle-icon--rotated { + transform: rotate(0deg); + } +body.sidebar-collapsed #sidebar .sidebar-dropup-trigger, + #sidebar.sidebar-collapsed .sidebar-dropup-trigger { + justify-content: center; + width: var(--sidebar-control-size); + height: var(--sidebar-control-size); + padding: 0; + margin-inline: auto; + border-radius: var(--radius-full); + } +body.sidebar-collapsed #sidebar .sidebar-dropup-trigger .sidebar-text, + #sidebar.sidebar-collapsed .sidebar-dropup-trigger .sidebar-text { + display: none; + } +body.sidebar-collapsed #sidebar .sidebar-dropup-trigger__chevron { + display: none; + } +body.sidebar-collapsed #sidebar .sidebar-dropup-trigger__glyph, + #sidebar.sidebar-collapsed .sidebar-dropup-trigger__glyph { + margin: 0; + } +body.sidebar-collapsed #sidebar .sidebar-nav-link:hover, + #sidebar.sidebar-collapsed .sidebar-nav-link:hover, + body.sidebar-collapsed #sidebar .sidebar-nav-link:focus-visible, + #sidebar.sidebar-collapsed .sidebar-nav-link:focus-visible { + --sidebar-nav-translate-x: 0; + } +@media (min-width: 768px) { + #sidebar { + transform: translateX(0) !important; + width: var(--sidebar-width); + overflow: visible; + } + + #app[data-sidebar-state="collapsed"] { + margin-left: calc( + var(--sidebar-width-collapsed) + var(--sidebar-content-gap) + ); + width: calc( + 100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap) + ); + max-width: calc( + 100vw - var(--sidebar-width-collapsed) - var(--sidebar-content-gap) + ); + } + + #app[data-sidebar-state="expanded"] { + margin-left: max( + calc(var(--sidebar-width-expanded-base) + var(--sidebar-content-gap)), + calc(var(--sidebar-dropup-content-width) + var(--sidebar-content-gap)) + ); + width: min( + calc( + 100vw - var(--sidebar-width-expanded-base) - + var(--sidebar-content-gap) + ), + calc( + 100vw - var(--sidebar-dropup-content-width) - + var(--sidebar-content-gap) + ) + ); + max-width: min( + calc( + 100vw - var(--sidebar-width-expanded-base) - + var(--sidebar-content-gap) + ), + calc( + 100vw - var(--sidebar-dropup-content-width) - + var(--sidebar-content-gap) + ) + ); + } + } +@keyframes card-motion-enter { + from { + opacity: 0; + transform: translateY(var(--motion-card-enter-translate)); + } + + to { + opacity: 1; + transform: translateY(0); + } + } +@keyframes video-thumbnail-fade-in { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } +@keyframes interface-fade-in { + from { + opacity: 0; + } + + to { + opacity: 1; + } + } +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(var(--motion-fade-in-translate)); + } + + to { + opacity: 1; + transform: translateY(0); + } + } +@keyframes spin { + to { + transform: rotate(360deg); + } + } +.status-line { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); + line-height: 1.375; + color: var(--text-primary); +} +/* Status log containers reserve space for dynamic messages. */ +.status-line.error { + color: var(--color-critical-strong); + } +.status-line.\!error { + color: var(--color-critical-strong) !important; + } +.status-line.success { + } +.status-line.\!success { + } +.status-line.warn { + color: var(--color-warning-strong); + } +/* Blog layout root scaffolding */ +@keyframes ztr-rotate { + 100% { + transform: rotate(360deg); + } + } +@keyframes ztr-dash { + 0% { + stroke-dasharray: 1, 150; + stroke-dashoffset: 0; + } + + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -35; + } + + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -124; + } + } +@keyframes svelte-181fgen-loader-animation { + 0% { + transform: rotate(0); + } + + to { + transform: rotate(360deg); + } + } +@keyframes svelte-181fgen-fade-in { + to { + opacity: 1; + } + } +.dm-app-shell { + display: flex; + flex-direction: column; + gap: var(--space-lg); + padding: var(--space-lg); + background: var(--surface-base); + color: var(--text-primary); + min-height: 100vh; + } +.profile-modal .dm-app-shell { + min-height: 0; + height: auto; + padding: 0; + gap: var(--space-md); + } +.dm-app-shell__sidebar, + .dm-app-shell__main { + border-radius: var(--radius-lg); + border: var(--border-width-hairline) solid var(--border-default); + background: var(--surface-panel); + box-shadow: var(--shadow-soft); + } +.profile-modal .dm-app-shell__sidebar, + .profile-modal .dm-app-shell__main { + height: auto; + min-height: 0; + border: none; + box-shadow: none; + background: transparent; + padding: 0; + } +.dm-app-shell__sidebar { + display: flex; + flex-direction: column; + gap: var(--space-md); + padding: var(--space-md); + } +.dm-app-shell__title { + font-size: var(--font-size-lg); + margin: 0; + } +.dm-app-shell__main { + flex: 1; + display: flex; + flex-direction: column; + gap: var(--space-md); + padding: var(--space-md); + background: var(--surface-raised); + } +.profile-modal .dm-app-shell__main, + .profile-modal .dm-app-shell__sidebar { + min-width: 0; + } +.dm-conversation-list { + display: flex; + flex-direction: column; + gap: var(--space-sm); + } +.dm-conversation-list__header { + display: flex; + justify-content: space-between; + align-items: center; + } +.dm-conversation-list__items { + display: flex; + flex-direction: column; + gap: var(--space-xs); + overflow-y: auto; + max-height: 60vh; + padding-right: var(--space-xs); + } +.dm-conversation-list__state { + font-size: var(--font-size-sm); + color: var(--text-muted); + padding: var(--space-md); + text-align: center; + background: var(--surface-sunken); + border-radius: var(--radius-md); + } +.dm-contact-row { + display: flex; + align-items: center; + gap: var(--space-sm); + padding: var(--space-sm) var(--space-md); + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--border-subtle); + background: transparent; + color: inherit; + text-align: left; + cursor: pointer; + } +.dm-contact-row:hover, + .dm-contact-row:focus-visible { + background: var(--surface-muted); + border-color: var(--border-strong); + outline: none; + } +.dm-contact-row--active { + background: var(--surface-sunken); + border-color: var(--border-strong); + } +.dm-contact-row__content { + display: flex; + flex-direction: column; + gap: var(--space-2xs); + flex: 1; + } +.dm-contact-row__header { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: var(--space-xs); + } +.dm-contact-row__meta { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + } +.dm-contact-row__name { + font-weight: 600; + } +.dm-contact-row__badge { + align-self: flex-start; + padding: var(--space-3xs) var(--space-xs); + border-radius: var(--radius-full); + background: var(--color-accent); + color: var(--color-white); + font-size: var(--font-size-3xs); + } +.dm-avatar { + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + border-radius: var(--radius-full); + background: var(--surface-sunken); + color: var(--text-muted); + font-weight: 600; + overflow: hidden; + border: var(--border-width-hairline) solid var(--border-subtle); + } +.dm-avatar--md { + width: var(--space-xl-plus); + height: var(--space-xl-plus); + min-width: var(--space-xl-plus); + min-height: var(--space-xl-plus); + } +.dm-avatar--sm { + width: var(--space-xl); + height: var(--space-xl); + min-width: var(--space-xl); + min-height: var(--space-xl); + } +.dm-avatar__image { + width: 100%; + height: 100%; + -o-object-fit: cover; + object-fit: cover; + } +.dm-message-thread { + display: flex; + flex-direction: column; + gap: var(--space-sm); + flex: 1; + min-height: 0; + } +.dm-message-thread__header { + display: flex; + align-items: baseline; + gap: var(--space-sm); + } +.dm-message-thread__title { + font-size: var(--font-size-base); + margin: 0; + } +.dm-message-thread__status { + font-size: var(--font-size-xs); + color: var(--text-muted); + } +.dm-message-thread__zap-summary { + display: inline-flex; + align-items: center; + gap: var(--space-xs); + padding: var(--space-2xs) var(--space-xs); + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--border-subtle); + background: var(--surface-sunken); + color: var(--text-muted); + font-size: var(--font-size-2xs); + } +.dm-message-thread__zap-label { + text-transform: uppercase; + letter-spacing: var(--tracking-wide); + } +.dm-message-thread__zap-total { + font-weight: 600; + color: var(--text-primary); + } +.dm-message-thread__zap-profile { + color: var(--text-muted); + } +.dm-message-thread__timeline { + display: flex; + flex-direction: column; + gap: var(--space-sm); + padding: var(--space-sm); + border-radius: var(--radius-md); + background: var(--surface-panel); + border: var(--border-width-hairline) solid var(--border-subtle); + overflow-y: auto; + min-height: var(--size-16rem); + } +.dm-message-thread__state { + padding: var(--space-md); + text-align: center; + color: var(--text-muted); + background: var(--surface-sunken); + border-radius: var(--radius-md); + } +.dm-message-row { + display: flex; + align-items: flex-end; + gap: var(--space-xs); + width: 100%; + } +.dm-message-avatar { + width: var(--space-xl); + height: var(--space-xl); + flex-shrink: 0; + border-radius: var(--radius-full); + -o-object-fit: cover; + object-fit: cover; + background-color: var(--surface-sunken); + border: var(--border-width-hairline) solid var(--border-subtle); + } +.dm-message-bubble { + max-width: 75%; + display: flex; + flex-direction: column; + gap: var(--space-2xs); + padding: var(--space-sm) var(--space-md); + border-radius: var(--radius-lg); + border: var(--border-width-hairline) solid var(--message-bubble-border); + background: var(--message-bubble-background); + color: var(--message-bubble-text); + } +.dm-message-bubble--outgoing .dm-message-bubble__meta, + .dm-message-bubble--outgoing .dm-message-bubble__status { + color: var(--color-white); + opacity: 0.9; + } +.dm-message-bubble__content { + font-size: var(--font-size-sm); + overflow-wrap: anywhere; + white-space: pre-wrap; + } +.dm-message-bubble__meta { + display: flex; + gap: var(--space-xs); + font-size: var(--font-size-2xs); + color: var(--message-bubble-meta); + } +.dm-message-bubble__status { + color: var(--text-muted); + } +.dm-message-bubble__status[data-status="pending"] { + color: var(--status-warning); + } +.dm-message-bubble__status[data-status="sending"] { + color: var(--status-info); + } +.dm-message-bubble__status[data-status="failed"] { + color: var(--status-danger); + } +.dm-message-thread__new { + align-self: center; + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--border-subtle); + padding: var(--space-2xs) var(--space-sm); + font-size: var(--font-size-2xs); + background: var(--surface-sunken); + color: var(--text-muted); + } +.dm-message-thread__new:hover, + .dm-message-thread__new:focus-visible { + background: var(--surface-overlay-panel-soft); + color: var(--text-primary); + outline: none; + } +.dm-day-divider { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: var(--space-xs); + color: var(--text-muted); + font-size: var(--font-size-2xs); + } +.dm-day-divider__line { + height: var(--border-width-hairline); + background: var(--border-subtle); + } +.dm-notification-center { + display: flex; + flex-direction: column; + gap: var(--space-sm); + } +.dm-notification-center__filters { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: var(--space-xs); + } +.dm-notification-center__filter-button { + border-radius: var(--radius-full); + border: var(--border-width-hairline) solid var(--border-subtle); + background: var(--surface-sunken); + padding: var(--space-2xs) var(--space-sm); + font-size: var(--font-size-2xs); + font-weight: 600; + color: var(--text-muted); + transition: + color var(--motion-duration-fast) var(--motion-ease-out), + background var(--motion-duration-fast) var(--motion-ease-out), + border-color var(--motion-duration-fast) var(--motion-ease-out); + } +.dm-notification-center__filter-button:hover, + .dm-notification-center__filter-button:focus-visible { + outline: none; + border-color: var(--border-strong); + background: var(--surface-raised); + color: var(--text-primary); + } +.dm-notification-center__filter-button--active { + border-color: var(--border-strong); + background: var(--surface-overlay-panel); + color: var(--text-primary); + } +.dm-notification-center__groups { + display: flex; + flex-direction: column; + gap: var(--space-md); + } +.dm-notification-center__group { + display: flex; + flex-direction: column; + gap: var(--space-xs); + } +.dm-notification-center__group-title { + font-size: var(--font-size-2xs); + font-weight: 600; + text-transform: uppercase; + letter-spacing: var(--tracking-wide); + color: var(--text-muted); + } +.dm-notification-center__list { + display: flex; + flex-direction: column; + gap: var(--space-xs); + } +.dm-notification-center__empty { + font-size: var(--font-size-xs); + color: var(--text-muted); + } +.dm-notification-item { + display: grid; + grid-template-columns: auto 1fr auto; + align-items: center; + gap: var(--space-sm); + padding: var(--space-sm); + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--border-subtle); + background: var(--surface-sunken); + font-size: var(--font-size-xs); + text-align: left; + transition: + border-color var(--motion-duration-fast) var(--motion-ease-out), + background var(--motion-duration-fast) var(--motion-ease-out); + } +.dm-notification-item:hover, + .dm-notification-item:focus-visible { + outline: none; + border-color: var(--border-strong); + background: var(--surface-raised); + } +.dm-notification-item__icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: var(--icon-size-md); + height: var(--icon-size-md); + border-radius: var(--radius-full); + background: var(--surface-overlay-panel-soft); + color: var(--text-muted); + font-size: var(--font-size-xs); + } +.dm-notification-item__body { + display: flex; + flex-direction: column; + gap: var(--space-2xs); + min-width: 0; + } +.dm-notification-item__title { + font-weight: 600; + color: var(--text-primary); + } +.dm-notification-item__message { + color: var(--text-muted); + } +.dm-notification-item__meta { + display: flex; + align-items: center; + gap: var(--space-2xs); + color: var(--text-muted); + } +.dm-notification-item__timestamp { + font-variant-numeric: tabular-nums; + white-space: nowrap; + } +.dm-composer { + display: flex; + flex-direction: column; + gap: var(--space-xs); + } +.dm-composer__label { + font-size: var(--font-size-xs); + color: var(--text-muted); + } +.dm-composer__input { + resize: vertical; + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--border-default); + background: var(--surface-base); + color: var(--text-primary); + padding: var(--space-sm); + font-family: inherit; + } +.dm-composer__input:focus-visible { + outline: var(--space-3xs) solid var(--color-accent); + outline-offset: var(--space-3xs); + } +.dm-composer__actions { + display: flex; + justify-content: space-between; + align-items: center; + gap: var(--space-sm); + } +.dm-composer__tools { + display: flex; + align-items: center; + gap: var(--space-sm); + flex-wrap: wrap; + position: relative; + } +.dm-composer__hint { + font-size: var(--font-size-2xs); + color: var(--text-muted); + } +.dm-composer__attach, + .dm-composer__more-btn { + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--border-default); + background: var(--surface-base); + color: var(--text-muted); + padding: var(--space-2xs) var(--space-sm); + font-size: var(--font-size-2xs); + cursor: pointer; + } +.dm-composer__more-btn { + font-weight: 700; + line-height: 1; + min-width: var(--space-xl); + } +.dm-composer__more-menu { + position: absolute; + bottom: 100%; + left: 0; + margin-bottom: var(--space-xs); + background: var(--surface-overlay-panel); + border: var(--border-width-hairline) solid var(--border-default); + border-radius: var(--radius-md); + box-shadow: var(--shadow-popover); + z-index: 10; + display: flex; + flex-direction: column; + min-width: var(--size-8rem); + padding: var(--space-xs); + } +.dm-composer__menu-item { + text-align: left; + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-sm); + font-size: var(--font-size-xs); + color: var(--text-muted); + background: transparent; + border: none; + cursor: pointer; + transition: background var(--motion-duration-fast) ease-out; + } +.dm-composer__menu-item:hover, + .dm-composer__menu-item:focus-visible { + background: var(--surface-overlay-panel-soft); + color: var(--text-primary); + outline: none; + } +.dm-composer__menu-item[aria-pressed="true"] { + background: var(--color-accent); + color: var(--color-white); + } +.dm-composer__attach:hover, + .dm-composer__attach:focus-visible, + .dm-composer__more-btn:hover, + .dm-composer__more-btn:focus-visible { + background: var(--surface-overlay-panel-soft); + color: var(--text-primary); + outline: none; + } +.dm-composer__send { + border-radius: var(--radius-md); + border: var(--border-width-hairline) solid var(--border-strong); + background: var(--surface-overlay-panel); + color: var(--text-primary); + padding: var(--space-xs) var(--space-md); + font-weight: 600; + cursor: pointer; + } +.dm-composer__send:hover, + .dm-composer__send:focus-visible { + background: var(--surface-overlay-panel-soft); + outline: none; + } +.dm-composer__status { + font-size: var(--font-size-2xs); + color: var(--status-danger); + min-height: var(--space-md); + } +@media (max-width: calc(768px - 0.02px)) { + .dm-app-shell[data-dm-view="list"] .dm-app-shell__main { + display: none !important; + } + + .dm-app-shell[data-dm-view="thread"] .dm-app-shell__sidebar { + display: none !important; + } + + .dm-message-thread__back { + display: inline-flex; + align-items: center; + gap: 0.5rem; + } + } +@media (min-width: 768px) { + .dm-app-shell { + flex-direction: row; + align-items: stretch; + } + + .dm-app-shell__sidebar { + flex: 0 0 var(--size-18rem); + max-width: var(--size-20rem); + height: calc(100vh - var(--space-lg) * 2); + display: flex !important; + } + + .dm-app-shell__main { + height: calc(100vh - var(--space-lg) * 2); + display: flex !important; + } + + .dm-conversation-list__items { + max-height: none; + flex: 1; + } + + .dm-message-thread__back { + display: none !important; + } + } +/* Ensure the profile pane for messages takes full height */ +#profilePaneMessages { + height: 100%; + min-height: 0; + } +@media (min-width: 768px) { + .profile-modal .dm-app-shell { + flex-direction: row; + align-items: stretch; + height: 100%; + min-height: 0; + } + + .profile-modal .dm-app-shell__sidebar { + flex: 0 0 var(--size-18rem); + max-width: var(--size-20rem); + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; + } + + .profile-modal .dm-app-shell__main { + flex: 1 1 auto; + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; + } + + .profile-modal .dm-conversation-list { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; + } + + .profile-modal .dm-conversation-list__items { + flex: 1; + overflow-y: auto; + min-height: 0; + overscroll-behavior-y: contain; + scrollbar-width: none; + -ms-overflow-style: none; + } +.profile-modal .dm-conversation-list__items::-webkit-scrollbar { + display: none; +} + + .profile-modal .dm-message-thread { + flex: 1; + min-height: 0; + display: flex; + flex-direction: column; + } + + .profile-modal .dm-message-thread__timeline { + flex: 1; + overflow-y: auto; + min-height: 0; + overscroll-behavior-y: contain; + scrollbar-width: none; + -ms-overflow-style: none; + } +.profile-modal .dm-message-thread__timeline::-webkit-scrollbar { + display: none; +} + } +@media (min-width: 1024px) { + .dm-app-shell__sidebar { + flex-basis: var(--size-20rem); + } + + .dm-message-thread__timeline { + padding: var(--space-md); + } + } +.marquee-host { + position: relative; + overflow: hidden; + white-space: nowrap; + width: 100%; + min-width: 0; + max-width: 100%; + } +.marquee-static { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + opacity: 1; + transition: opacity 0.3s ease; +} +.marquee-anim { + position: absolute; + inset: 0; + display: flex; + align-items: center; + opacity: 0; + transition: opacity 0.3s ease; + pointer-events: none; + mask-image: linear-gradient( + to right, + transparent, + black 4%, + black 96%, + transparent + ); + -webkit-mask-image: linear-gradient( + to right, + transparent, + black 4%, + black 96%, + transparent + ); + } +.marquee-track { + display: flex; + width: -moz-max-content; + width: max-content; + animation: marquee-scroll linear infinite; + animation-duration: var(--marquee-duration, 10s); + animation-play-state: paused; + } +.marquee-item { + flex-shrink: 0; + padding-right: var(--space-xl); /* Gap between loop items */ + } +@keyframes marquee-scroll { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(-50%); + } + } +/* Desktop Hover State */ +@media (min-width: 1024px) { + .\!card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .\!card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card:hover .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + } +/* Mobile Active State */ +@media (max-width: calc(1024px - var(--breakpoint-edge-offset))) { + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate); + --video-card-backdrop-opacity: 0.425; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ); + --video-card-backdrop-scale: 1.12; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong); + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent); + } + + .card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0; + } + .card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1; + } + .card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running; + } + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + .\!card[data-mobile-active="true"] { + --video-card-lift-translate-y: var(--motion-video-card-hover-translate) !important; + --video-card-backdrop-opacity: 0.425 !important; + --video-card-backdrop-translate-y: var( + --motion-video-card-backdrop-translate + ) !important; + --video-card-backdrop-scale: 1.12 !important; + --video-card-backdrop-blur: var(--blur-video-card-backdrop-strong) !important; + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + } + + .\!card[data-mobile-active="true"] .video-card__title { + color: var(--color-accent) !important; + } + + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-static { + opacity: 0 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-anim { + opacity: 1 !important; + } + .\!card[data-mobile-active="true"] .marquee-host.can-marquee .marquee-track { + animation-play-state: running !important; + } + } +/* Logo accent wiring */ +.bv-logo__accent { + fill: var(--bitvid-accent, var(--logo-accent-color)); + } +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} +.pointer-events-none { + pointer-events: none; +} +.pointer-events-auto { + pointer-events: auto; +} +.\!visible { + visibility: visible !important; +} +.visible { + visibility: visible; +} +.collapse { + visibility: collapse; +} +.static { + position: static; +} +.fixed { + position: fixed; +} +.absolute { + position: absolute; +} +.relative { + position: relative; +} +.sticky { + position: sticky; +} +.inset-0 { + inset: 0px; +} +.inset-x-0 { + left: 0px; + right: 0px; +} +.bottom-16 { + bottom: 4rem; +} +.bottom-4 { + bottom: 1rem; +} +.bottom-6 { + bottom: 1.5rem; +} +.left-1\/2 { + left: 50%; +} +.left-4 { + left: 1rem; +} +.right-2 { + right: 0.5rem; +} +.right-3 { + right: 0.75rem; +} +.right-4 { + right: 1rem; +} +.right-6 { + right: 1.5rem; +} +.top-0 { + top: 0px; +} +.top-1\/2 { + top: 50%; +} +.top-12 { + top: 3rem; +} +.top-2 { + top: 0.5rem; +} +.top-3 { + top: 0.75rem; +} +.top-4 { + top: 1rem; +} +.z-10 { + z-index: 10; +} +.z-20 { + z-index: 20; +} +.z-50 { + z-index: 50; +} +.z-overlay-floating { + z-index: var(--z-overlay-floating); +} +.z-overlay-toast { + z-index: var(--z-overlay-toast); +} +.order-1 { + order: 1; +} +.order-2 { + order: 2; +} +.col-span-full { + grid-column: 1 / -1; +} +.mx-1 { + margin-left: 0.25rem; + margin-right: 0.25rem; +} +.mx-auto { + margin-left: auto; + margin-right: auto; +} +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} +.my-6 { + margin-top: 1.5rem; + margin-bottom: 1.5rem; +} +.-ml-1 { + margin-left: -0.25rem; +} +.-ml-2 { + margin-left: -0.5rem; +} +.mb-1 { + margin-bottom: 0.25rem; +} +.mb-2 { + margin-bottom: 0.5rem; +} +.mb-3 { + margin-bottom: 0.75rem; +} +.mb-4 { + margin-bottom: 1rem; +} +.mb-6 { + margin-bottom: 1.5rem; +} +.mb-8 { + margin-bottom: 2rem; +} +.ml-1 { + margin-left: 0.25rem; +} +.ml-2 { + margin-left: 0.5rem; +} +.ml-4 { + margin-left: 1rem; +} +.ml-auto { + margin-left: auto; +} +.ml-md { + margin-left: var(--space-md); +} +.mt-0\.5 { + margin-top: 0.125rem; +} +.mt-1 { + margin-top: 0.25rem; +} +.mt-1\.5 { + margin-top: 0.375rem; +} +.mt-2 { + margin-top: 0.5rem; +} +.mt-3 { + margin-top: 0.75rem; +} +.mt-4 { + margin-top: 1rem; +} +.mt-6 { + margin-top: 1.5rem; +} +.mt-8 { + margin-top: 2rem; +} +.mt-auto { + margin-top: auto; +} +.mt-sm { + margin-top: var(--space-sm); +} +.line-clamp-2 { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; +} +.block { + display: block; +} +.inline-block { + display: inline-block; +} +.inline { + display: inline; +} +.flex { + display: flex; +} +.inline-flex { + display: inline-flex; +} +.table { + display: table; +} +.grid { + display: grid; +} +.contents { + display: contents; +} +.hidden { + display: none; +} +.aspect-square { + aspect-ratio: 1 / 1; +} +.aspect-video { + aspect-ratio: 16 / 9; +} +.h-1 { + height: 0.25rem; +} +.h-1\.5 { + height: 0.375rem; +} +.h-10 { + height: 2.5rem; +} +.h-12 { + height: 3rem; +} +.h-14 { + height: 3.5rem; +} +.h-16 { + height: 4rem; +} +.h-24 { + height: 6rem; +} +.h-2xl { + height: var(--space-2xl); +} +.h-3 { + height: 0.75rem; +} +.h-3\.5 { + height: 0.875rem; +} +.h-32 { + height: 8rem; +} +.h-4 { + height: 1rem; +} +.h-4\/5 { + height: 80%; +} +.h-40 { + height: 10rem; +} +.h-48 { + height: 12rem; +} +.h-5 { + height: 1.25rem; +} +.h-6 { + height: 1.5rem; +} +.h-8 { + height: 2rem; +} +.h-9 { + height: 2.25rem; +} +.h-\[80vh\] { + height: 80vh; +} +.h-auto { + height: auto; +} +.h-full { + height: 100%; +} +.h-px { + height: 1px; +} +.h-screen { + height: 100vh; +} +.max-h-\[90vh\] { + max-height: 90vh; +} +.max-h-\[980px\] { + max-height: 980px; +} +.max-h-modal-body { + max-height: var(--modal-body-max-height); +} +.max-h-modal-pane { + max-height: var(--modal-pane-max-height); +} +.max-h-modal-sheet { + max-height: var(--modal-sheet-max-height); +} +.max-h-modal-shell { + max-height: var(--modal-shell-max-height); +} +.min-h-0 { + min-height: 0px; +} +.min-h-\[200px\] { + min-height: 200px; +} +.min-h-\[var\(--size-80px\)\] { + min-height: var(--size-80px); +} +.min-h-screen { + min-height: 100vh; +} +.w-10 { + width: 2.5rem; +} +.w-12 { + width: 3rem; +} +.w-14 { + width: 3.5rem; +} +.w-16 { + width: 4rem; +} +.w-20 { + width: 5rem; +} +.w-24 { + width: 6rem; +} +.w-28 { + width: 7rem; +} +.w-3 { + width: 0.75rem; +} +.w-3\.5 { + width: 0.875rem; +} +.w-32 { + width: 8rem; +} +.w-4 { + width: 1rem; +} +.w-44 { + width: 11rem; +} +.w-48 { + width: 12rem; +} +.w-5 { + width: 1.25rem; +} +.w-56 { + width: 14rem; +} +.w-6 { + width: 1.5rem; +} +.w-72 { + width: 18rem; +} +.w-8 { + width: 2rem; +} +.w-80 { + width: 20rem; +} +.w-9 { + width: 2.25rem; +} +.w-auto { + width: auto; +} +.w-full { + width: 100%; +} +.w-screen { + width: 100vw; +} +.min-w-0 { + min-width: 0px; +} +.min-w-full { + min-width: 100%; +} +.max-w-2xl { + max-width: 42rem; +} +.max-w-3xl { + max-width: 48rem; +} +.max-w-4xl { + max-width: 56rem; +} +.max-w-5xl { + max-width: 64rem; +} +.max-w-7xl { + max-width: 80rem; +} +.max-w-\[200px\] { + max-width: 200px; +} +.max-w-docs { + max-width: var(--layout-docs-max-width); +} +.max-w-lg { + max-width: 32rem; +} +.max-w-md { + max-width: 28rem; +} +.max-w-none { + max-width: none; +} +.max-w-popover-safe { + max-width: var(--popover-inline-safe-max); +} +.max-w-sm { + max-width: 24rem; +} +.max-w-xs { + max-width: 20rem; +} +.flex-1 { + flex: 1 1 0%; +} +.flex-shrink-0 { + flex-shrink: 0; +} +.shrink-0 { + flex-shrink: 0; +} +.flex-grow { + flex-grow: 1; +} +.grow { + flex-grow: 1; +} +.origin-top { + transform-origin: top; +} +.-translate-x-1\/2 { + --tw-translate-x: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.-translate-y-1\/2 { + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.rotate-0 { + --tw-rotate: 0deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.rotate-180 { + --tw-rotate: 180deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.rotate-90 { + --tw-rotate: 90deg; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.scale-\[1\.2\] { + --tw-scale-x: 1.2; + --tw-scale-y: 1.2; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.transform { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +@keyframes pulse { + 50% { + opacity: .5; + } +} +.animate-pulse { + animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} +@keyframes spin { + to { + transform: rotate(360deg); + } +} +.animate-spin { + animation: spin 1s linear infinite; +} +.cursor-not-allowed { + cursor: not-allowed; +} +.cursor-pointer { + cursor: pointer; +} +.cursor-wait { + cursor: wait; +} +.select-none { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +.select-all { + -webkit-user-select: all; + -moz-user-select: all; + user-select: all; +} +.resize-y { + resize: vertical; +} +.resize { + resize: both; +} +.list-disc { + list-style-type: disc; +} +.auto-rows-fr { + grid-auto-rows: minmax(0, 1fr); +} +.grid-cols-1 { + grid-template-columns: repeat(1, minmax(0, 1fr)); +} +.grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} +.grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} +.flex-row { + flex-direction: row; +} +.flex-col { + flex-direction: column; +} +.flex-wrap { + flex-wrap: wrap; +} +.items-start { + align-items: flex-start; +} +.items-end { + align-items: flex-end; +} +.items-center { + align-items: center; +} +.items-stretch { + align-items: stretch; +} +.justify-start { + justify-content: flex-start; +} +.justify-end { + justify-content: flex-end; +} +.justify-center { + justify-content: center; +} +.justify-between { + justify-content: space-between; +} +.gap-1 { + gap: 0.25rem; +} +.gap-1\.5 { + gap: 0.375rem; +} +.gap-12 { + gap: 3rem; +} +.gap-2 { + gap: 0.5rem; +} +.gap-3 { + gap: 0.75rem; +} +.gap-4 { + gap: 1rem; +} +.gap-6 { + gap: 1.5rem; +} +.gap-8 { + gap: 2rem; +} +.gap-lg { + gap: var(--space-lg); +} +.gap-sm { + gap: var(--space-sm); +} +.gap-xl { + gap: var(--space-xl); +} +.gap-xs { + gap: var(--space-xs); +} +.gap-x-2 { + -moz-column-gap: 0.5rem; + column-gap: 0.5rem; +} +.gap-x-3 { + -moz-column-gap: 0.75rem; + column-gap: 0.75rem; +} +.gap-y-1 { + row-gap: 0.25rem; +} +.gap-y-6 { + row-gap: 1.5rem; +} +.gap-y-8 { + row-gap: 2rem; +} +.space-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} +.space-x-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.75rem * var(--tw-space-x-reverse)); + margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); +} +.space-x-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} +.space-y-1 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); +} +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} +.space-y-5 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.25rem * var(--tw-space-y-reverse)); +} +.space-y-6 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); +} +.space-y-8 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(2rem * var(--tw-space-y-reverse)); +} +.divide-y > :not([hidden]) ~ :not([hidden]) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} +.divide-border-translucent > :not([hidden]) ~ :not([hidden]) { + border-color: var(--border-overlay); +} +.self-start { + align-self: flex-start; +} +.overflow-auto { + overflow: auto; +} +.overflow-hidden { + overflow: hidden; +} +.overflow-x-auto { + overflow-x: auto; +} +.overflow-y-auto { + overflow-y: auto; +} +.truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.whitespace-nowrap { + white-space: nowrap; +} +.whitespace-pre-line { + white-space: pre-line; +} +.whitespace-pre-wrap { + white-space: pre-wrap; +} +.break-words { + overflow-wrap: break-word; +} +.break-all { + word-break: break-all; +} +.rounded { + border-radius: 0.25rem; +} +.rounded-2xl { + border-radius: 1rem; +} +.rounded-3xl { + border-radius: 1.5rem; +} +.rounded-full { + border-radius: var(--radius-full); +} +.rounded-lg { + border-radius: var(--radius-lg); +} +.rounded-md { + border-radius: var(--radius-md); +} +.rounded-none { + border-radius: 0px; +} +.rounded-xl { + border-radius: var(--radius-xl); +} +.rounded-r-md { + border-top-right-radius: var(--radius-md); + border-bottom-right-radius: var(--radius-md); +} +.rounded-t-lg { + border-top-left-radius: var(--radius-lg); + border-top-right-radius: var(--radius-lg); +} +.border { + border-width: 1px; +} +.border-0 { + border-width: 0px; +} +.border-2 { + border-width: 2px; +} +.border-b { + border-bottom-width: 1px; +} +.border-l { + border-left-width: 1px; +} +.border-l-2 { + border-left-width: 2px; +} +.border-l-4 { + border-left-width: 4px; +} +.border-r { + border-right-width: 1px; +} +.border-t { + border-top-width: 1px; +} +.border-dashed { + border-style: dashed; +} +.border-none { + border-style: none; +} +.border-accent { + border-color: var(--color-accent); +} +.border-border { + border-color: var(--border-default); +} +.border-border-strong { + border-color: var(--border-strong); +} +.border-border-subtle { + border-color: var(--border-subtle); +} +.border-border-translucent { + border-color: var(--border-overlay); +} +.border-border-translucent-bright { + border-color: var(--color-border-translucent-bright); +} +.border-border-translucent-medium { + border-color: var(--color-border-translucent-medium); +} +.border-overlay { + border-color: var(--border-overlay); +} +.border-overlay-strong { + border-color: var(--border-overlay-strong); +} +.border-status-danger-border { + border-color: var(--status-danger-border); +} +.border-status-info { + border-color: var(--status-info); +} +.border-status-info-border { + border-color: var(--status-info-border); +} +.border-status-success-border { + border-color: var(--status-success-border); +} +.border-status-warning-border { + border-color: var(--status-warning-border); +} +.border-surface-strong { + border-color: var(--border-strong); +} +.border-transparent { + border-color: transparent; +} +.border-opacity-20 { + --tw-border-opacity: 0.2; +} +.border-opacity-40 { + --tw-border-opacity: 0.4; +} +.bg-accent-strong { + background-color: var(--color-accent-strong); +} +.bg-overlay-muted { + background-color: var(--surface-overlay-muted); +} +.bg-overlay-panel { + background-color: var(--surface-overlay-panel); +} +.bg-overlay-panel-soft { + background-color: var(--surface-overlay-panel-soft); +} +.bg-overlay-strong { + background-color: var(--surface-overlay-strong); +} +.bg-panel { + background-color: var(--surface-panel); +} +.bg-status-danger-surface { + background-color: var(--status-danger-surface); +} +.bg-status-info-surface { + background-color: var(--status-info-surface); +} +.bg-status-success-surface { + background-color: var(--status-success-surface); +} +.bg-status-warning-surface { + background-color: var(--status-warning-surface); +} +.bg-surface { + background-color: var(--surface-base); +} +.bg-surface-alt { + background-color: var(--surface-alt); +} +.bg-surface-muted { + background-color: var(--surface-muted); +} +.bg-transparent { + background-color: transparent; +} +.bg-white { + background-color: var(--color-white); +} +.bg-opacity-95 { + --tw-bg-opacity: 0.95; +} +.bg-gradient-to-b { + background-image: linear-gradient(to bottom, var(--tw-gradient-stops)); +} +.bg-overlay-channel { + background-image: var(--surface-overlay-banner-gradient-channel); +} +.via-transparent { + --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position); + --tw-gradient-stops: var(--tw-gradient-from), transparent var(--tw-gradient-via-position), var(--tw-gradient-to); +} +.to-transparent { + --tw-gradient-to: transparent var(--tw-gradient-to-position); +} +.stroke-border-translucent { + stroke: var(--border-overlay); +} +.stroke-current { + stroke: currentColor; +} +.object-cover { + -o-object-fit: cover; + object-fit: cover; +} +.p-0 { + padding: 0px; +} +.p-1 { + padding: 0.25rem; +} +.p-2 { + padding: 0.5rem; +} +.p-3 { + padding: 0.75rem; +} +.p-4 { + padding: 1rem; +} +.p-5 { + padding: 1.25rem; +} +.p-6 { + padding: 1.5rem; +} +.p-8 { + padding: 2rem; +} +.p-lg { + padding: var(--space-lg); +} +.p-md { + padding: var(--space-md); +} +.px-0 { + padding-left: 0px; + padding-right: 0px; +} +.px-1 { + padding-left: 0.25rem; + padding-right: 0.25rem; +} +.px-1\.5 { + padding-left: 0.375rem; + padding-right: 0.375rem; +} +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} +.px-5 { + padding-left: 1.25rem; + padding-right: 1.25rem; +} +.px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; +} +.px-lg { + padding-left: var(--space-lg); + padding-right: var(--space-lg); +} +.px-md { + padding-left: var(--space-md); + padding-right: var(--space-md); +} +.py-0 { + padding-top: 0px; + padding-bottom: 0px; +} +.py-0\.5 { + padding-top: 0.125rem; + padding-bottom: 0.125rem; +} +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} +.py-1\.5 { + padding-top: 0.375rem; + padding-bottom: 0.375rem; +} +.py-12 { + padding-top: 3rem; + padding-bottom: 3rem; +} +.py-16 { + padding-top: 4rem; + padding-bottom: 4rem; +} +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.py-3 { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} +.py-4 { + padding-top: 1rem; + padding-bottom: 1rem; +} +.py-5 { + padding-top: 1.25rem; + padding-bottom: 1.25rem; +} +.py-6 { + padding-top: 1.5rem; + padding-bottom: 1.5rem; +} +.py-8 { + padding-top: 2rem; + padding-bottom: 2rem; +} +.py-md { + padding-top: var(--space-md); + padding-bottom: var(--space-md); +} +.py-xl { + padding-top: var(--space-xl); + padding-bottom: var(--space-xl); +} +.pb-16 { + padding-bottom: 4rem; +} +.pb-2 { + padding-bottom: 0.5rem; +} +.pb-4 { + padding-bottom: 1rem; +} +.pb-6 { + padding-bottom: 1.5rem; +} +.pb-8 { + padding-bottom: 2rem; +} +.pl-2 { + padding-left: 0.5rem; +} +.pl-5 { + padding-left: 1.25rem; +} +.pl-6 { + padding-left: 1.5rem; +} +.pl-md { + padding-left: var(--space-md); +} +.pr-1 { + padding-right: 0.25rem; +} +.pt-1 { + padding-top: 0.25rem; +} +.pt-2 { + padding-top: 0.5rem; +} +.pt-4 { + padding-top: 1rem; +} +.pt-5 { + padding-top: 1.25rem; +} +.pt-6 { + padding-top: 1.5rem; +} +.text-left { + text-align: left; +} +.text-center { + text-align: center; +} +.text-right { + text-align: right; +} +.align-top { + vertical-align: top; +} +.align-middle { + vertical-align: middle; +} +.font-mono { + font-family: var(--font-family-mono); +} +.font-sans { + font-family: var(--font-family-sans); +} +.text-2xl { + font-size: var(--font-size-2xl); + line-height: var(--line-height-relaxed); +} +.text-2xs { + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); +} +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} +.text-3xs { + font-size: var(--font-size-3xs); + line-height: var(--line-height-tight); +} +.text-4xl { + font-size: 2.25rem; + line-height: 2.5rem; +} +.text-\[0\.75rem\] { + font-size: 0.75rem; +} +.text-base { + font-size: var(--font-size-base); + line-height: var(--line-height-base); +} +.text-lg { + font-size: var(--font-size-lg); + line-height: var(--line-height-base); +} +.text-sm { + font-size: var(--font-size-sm); + line-height: var(--line-height-snug); +} +.text-xl { + font-size: var(--font-size-xl); + line-height: var(--line-height-relaxed); +} +.text-xs { + font-size: var(--font-size-xs); + line-height: var(--line-height-tight); +} +.font-bold { + font-weight: 700; +} +.font-extrabold { + font-weight: 800; +} +.font-medium { + font-weight: 500; +} +.font-semibold { + font-weight: 600; +} +.uppercase { + text-transform: uppercase; +} +.lowercase { + text-transform: lowercase; +} +.normal-case { + text-transform: none; +} +.italic { + font-style: italic; +} +.ordinal { + --tw-ordinal: ordinal; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} +.tabular-nums { + --tw-numeric-spacing: tabular-nums; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} +.leading-none { + line-height: 1; +} +.leading-relaxed { + line-height: 1.625; +} +.leading-snug { + line-height: 1.375; +} +.tracking-extra-wide { + letter-spacing: var(--tracking-extra-wide); +} +.tracking-tight { + letter-spacing: -0.025em; +} +.tracking-wide { + letter-spacing: 0.025em; +} +.tracking-wider { + letter-spacing: 0.05em; +} +.text-accent { + color: var(--color-accent); +} +.text-black { + color: var(--color-black); +} +.text-critical { + color: var(--color-critical); +} +.text-critical-strong { + color: var(--color-critical-strong); +} +.text-info { + color: var(--color-info); +} +.text-info-strong { + color: var(--color-info-strong); +} +.text-muted { + color: var(--text-muted); +} +.text-muted-strong { + color: var(--text-muted-strong); +} +.text-primary { + color: var(--text-primary); +} +.text-status-danger { + color: var(--status-danger); +} +.text-status-danger-on { + color: var(--status-danger-on); +} +.text-status-info { + color: var(--status-info); +} +.text-status-info-on { + color: var(--status-info-on); +} +.text-status-neutral { + color: var(--status-neutral); +} +.text-status-private-on { + color: var(--status-private-on); +} +.text-status-success { + color: var(--status-success); +} +.text-status-success-on { + color: var(--status-success-on); +} +.text-status-warning { + color: var(--status-warning); +} +.text-status-warning-on { + color: var(--status-warning-on); +} +.text-subtle { + color: var(--text-subtle); +} +.text-text { + color: var(--text-primary); +} +.text-text-frosted { + color: var(--text-frosted-primary); +} +.text-text-muted { + color: var(--text-muted); +} +.text-text-strong { + color: var(--color-text-strong); +} +.text-warning { + color: var(--status-warning); +} +.text-warning-strong { + color: var(--status-warning-strong); +} +.text-white { + color: var(--color-white); +} +.underline { + text-decoration-line: underline; +} +.decoration-dotted { + text-decoration-style: dotted; +} +.underline-offset-2 { + text-underline-offset: 2px; +} +.opacity-0 { + opacity: 0; +} +.opacity-20 { + opacity: 0.2; +} +.opacity-40 { + opacity: 0.4; +} +.opacity-50 { + opacity: 0.5; +} +.opacity-60 { + opacity: 0.6; +} +.opacity-70 { + opacity: 0.7; +} +.opacity-80 { + opacity: 0.8; +} +.opacity-95 { + opacity: 0.95; +} +.shadow-2xl { + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.shadow-inner { + --tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05); + --tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.shadow-lg { + --tw-shadow: var(--shadow-lg); + --tw-shadow-colored: var(--shadow-lg); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.shadow-md { + --tw-shadow: var(--shadow-md); + --tw-shadow-colored: var(--shadow-md); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.shadow-sm { + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.shadow-xl { + --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.outline-none { + outline: 2px solid transparent; + outline-offset: 2px; +} +.outline { + outline-style: solid; +} +.blur { + --tw-blur: blur(8px); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} +.blur-xl { + --tw-blur: blur(24px); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} +.drop-shadow-md { + --tw-drop-shadow: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06)); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} +.\!filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important; +} +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} +.backdrop-blur-md { + --tw-backdrop-blur: blur(12px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} +.backdrop-blur-sm { + --tw-backdrop-blur: blur(4px); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); +} +.transition { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.transition-all { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.transition-colors { + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.transition-opacity { + transition-property: opacity; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.transition-transform { + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} +.duration-150 { + transition-duration: 150ms; +} +.duration-200 { + transition-duration: 200ms; +} +.duration-300 { + transition-duration: 300ms; +} +.duration-fast { + transition-duration: var(--motion-duration-fast); +} +.ease-out { + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); +} +@media (max-width: 640px) { + .bv-grid-video { + gap: var(--space-md); + grid-template-columns: 1fr; + } +} +@media (prefers-reduced-motion: reduce) { + :root { + --motion-duration-fast: 0s; + --motion-duration-base: 0s; + --motion-duration-slow: 0s; + --modal-motion-duration: 0s; + } + + *, + *::before, + *::after { + animation-delay: 0s !important; + animation-duration: 0s !important; + animation-iteration-count: 1 !important; + animation-timing-function: linear !important; + transition-delay: 0s !important; + transition-duration: 0s !important; + transition-timing-function: linear !important; + } + + .player-modal__similar-card::before { + transition: none !important; + } + + .btn, + .btn-ghost, + .card, + .card[data-motion="enter"], + .fade-in, + .icon-button, + .menu__item, + .modal-nav, + .popover-panel, + .popover__panel, + .progress-bar-fill, + .notification-banner, + .notification-portal, + .torrent-toast, + .status-banner .status-spinner, + .status-spinner--inline, + .video-modal__panel, + .watch-history-card, + .watch-history-card__creatorAvatar, + .watch-history-card__creatorName, + .watch-history-card__action, + .watch-history-card__title, + #app, + #playerModal .player-modal__content, + #sidebar, + .sidebar-collapse-toggle, + .sidebar-collapse-toggle__icon, + .sidebar-dropup-panel, + .sidebar-dropup-trigger, + .sidebar-dropup-trigger__chevron, + .sidebar-nav, + .sidebar-nav-link, + .sidebar-loading-indicator, + .sidebar-loading-wrapper { + transition-property: none !important; + } + + .popover-panel, + .popover__panel { + transform: none !important; + } + + .popover-panel[data-state="open"], + .popover__panel[data-state="open"] { + opacity: 1; + } + + .popover-panel[data-state="closed"], + .popover__panel[data-state="closed"] { + opacity: 0; + } + + .card[data-motion="enter"], + .fade-in { + opacity: 1; + animation: none !important; + } + + [data-video-thumbnail][data-thumbnail-loaded="true"] { + animation: none !important; + opacity: 1; + } + + .notification-banner, + .torrent-toast, + .status-banner .status-spinner, + .status-spinner--inline { + animation: none !important; + } + + .notification-portal { + transform: none !important; + opacity: 1 !important; + } +} +/* Profile Modal Full Screen Overrides */ +#profileModal { + padding: 0; + width: 100vw; + height: 100vh; + max-width: none; + max-height: none; +} +#profileModal .bv-modal__panel { + width: 100%; + height: 100%; + max-width: none; + max-height: none; + border-radius: 0; + border: none; +} +/* Override responsive max-height constraint */ +@media (min-width: 1024px) { + #profileModal .profile-modal { + max-block-size: none; + } +} +.no-scrollbar { + scrollbar-width: none !important; + -ms-overflow-style: none !important; +} +.no-scrollbar::-webkit-scrollbar { + display: none !important; +} +/* Embed & Video Modal Fixes */ +.empty\:hidden:empty + .bv-modal { + display: none !important; + } +.empty\:hidden:empty.profile-pane { + display: none !important; + } +@media (min-width: 768px) { + + .md\:hidden + .bv-modal { + display: none !important; + } + + .md\:hidden.profile-pane { + display: none !important; + } +} +@media (min-width: 1024px) { + + .lg\:hidden + .bv-modal { + display: none !important; + } + + .lg\:hidden.profile-pane { + display: none !important; + } +} +.placeholder\:text-muted::-moz-placeholder { + color: var(--text-muted); +} +.placeholder\:text-muted::placeholder { + color: var(--text-muted); +} +.empty\:hidden:empty { + display: none; +} +.hover\:scale-105:hover { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.hover\:border-status-danger-border:hover { + border-color: var(--status-danger-border); +} +.hover\:bg-overlay-panel:hover { + background-color: var(--surface-overlay-panel); +} +.hover\:bg-panel-hover:hover { + background-color: var(--surface-panel-hover); +} +.hover\:text-accent:hover { + color: var(--color-accent); +} +.hover\:text-accent-strong:hover { + color: var(--color-accent-strong); +} +.hover\:text-critical:hover { + color: var(--color-critical); +} +.hover\:text-info-strong:hover { + color: var(--color-info-strong); +} +.hover\:text-status-danger-strong:hover { + color: var(--status-danger-strong); +} +.hover\:text-text:hover { + color: var(--text-primary); +} +.hover\:text-text-strong:hover { + color: var(--color-text-strong); +} +.hover\:underline:hover { + text-decoration-line: underline; +} +.hover\:opacity-80:hover { + opacity: 0.8; +} +.hover\:opacity-90:hover { + opacity: 0.9; +} +.hover\:shadow-sm:hover { + --tw-shadow: var(--shadow-sm); + --tw-shadow-colored: var(--shadow-sm); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} +.focus\:outline-none:focus { + outline: 2px solid transparent; + outline-offset: 2px; +} +.focus\:ring-0:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.focus\:ring-2:focus { + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); + box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); +} +.focus\:ring-accent:focus { + --tw-ring-color: var(--color-accent); +} +.focus\:ring-info:focus { + --tw-ring-color: var(--color-info); +} +.focus\:ring-status-info:focus { + --tw-ring-color: var(--status-info); +} +.focus\:ring-status-success:focus { + --tw-ring-color: var(--status-success); +} +.focus\:ring-offset-2:focus { + --tw-ring-offset-width: 2px; +} +.focus\:ring-offset-surface:focus { + --tw-ring-offset-color: var(--surface-base); +} +.focus-visible\:bg-primary:focus-visible { + background-color: var(--color-primary); +} +.focus-visible\:outline:focus-visible { + outline-style: solid; +} +.focus-visible\:outline-2:focus-visible { + outline-width: 2px; +} +.focus-visible\:outline-offset-2:focus-visible { + outline-offset: 2px; +} +.focus-visible\:outline-info:focus-visible { + outline-color: var(--color-info); +} +.active\:scale-95:active { + --tw-scale-x: .95; + --tw-scale-y: .95; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.disabled\:cursor-not-allowed:disabled { + cursor: not-allowed; +} +.disabled\:opacity-50:disabled { + opacity: 0.5; +} +.group:hover .group-hover\:scale-105 { + --tw-scale-x: 1.05; + --tw-scale-y: 1.05; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} +.group:hover .group-hover\:text-primary { + color: var(--text-primary); +} +.group:hover .group-hover\:opacity-100 { + opacity: 1; +} +@media not all and (min-width: 640px) { + .max-sm\:h-12 { + height: 3rem; + } + .max-sm\:w-12 { + width: 3rem; + } + .max-sm\:text-2xs { + font-size: var(--font-size-2xs); + line-height: var(--line-height-tight); + } + .max-sm\:text-base { + font-size: var(--font-size-base); + line-height: var(--line-height-base); + } +} +@media (min-width: 640px) { + .sm\:order-1 { + order: 1; + } + .sm\:order-2 { + order: 2; + } + .sm\:col-span-2 { + grid-column: span 2 / span 2; + } + .sm\:flex { + display: flex; + } + .sm\:w-1\/3 { + width: 33.333333%; + } + .sm\:w-32 { + width: 8rem; + } + .sm\:w-48 { + width: 12rem; + } + .sm\:w-auto { + width: auto; + } + .sm\:max-w-xs { + max-width: 20rem; + } + .sm\:flex-none { + flex: none; + } + .sm\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .sm\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .sm\:flex-row { + flex-direction: row; + } + .sm\:flex-wrap { + flex-wrap: wrap; + } + .sm\:items-start { + align-items: flex-start; + } + .sm\:items-end { + align-items: flex-end; + } + .sm\:items-center { + align-items: center; + } + .sm\:justify-end { + justify-content: flex-end; + } + .sm\:justify-between { + justify-content: space-between; + } + .sm\:gap-2 { + gap: 0.5rem; + } + .sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0px * var(--tw-space-y-reverse)); + } + .sm\:self-end { + align-self: flex-end; + } + .sm\:p-0 { + padding: 0px; + } + .sm\:p-4 { + padding: 1rem; + } + .sm\:p-5 { + padding: 1.25rem; + } + .sm\:px-6 { + padding-left: 1.5rem; + padding-right: 1.5rem; + } + .sm\:py-0 { + padding-top: 0px; + padding-bottom: 0px; + } + .sm\:pt-8 { + padding-top: 2rem; + } +} +@media (min-width: 768px) { + .md\:col-span-2 { + grid-column: span 2 / span 2; + } + .md\:flex { + display: flex; + } + .md\:hidden { + display: none; + } + .md\:h-64 { + height: 16rem; + } + .md\:w-1\/3 { + width: 33.333333%; + } + .md\:w-2\/3 { + width: 66.666667%; + } + .md\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .md\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .md\:flex-row { + flex-direction: row; + } + .md\:items-end { + align-items: flex-end; + } + .md\:items-center { + align-items: center; + } + .md\:justify-end { + justify-content: flex-end; + } + .md\:gap-md { + gap: var(--space-md); + } + .md\:pb-12 { + padding-bottom: 3rem; + } +} +@media (min-width: 1024px) { + .lg\:ml-auto { + margin-left: auto; + } + .lg\:block { + display: block; + } + .lg\:flex { + display: flex; + } + .lg\:hidden { + display: none; + } + .lg\:h-auto { + height: auto; + } + .lg\:max-h-modal-shell { + max-height: var(--modal-shell-max-height); + } + .lg\:w-64 { + width: 16rem; + } + .lg\:max-w-4xl { + max-width: 56rem; + } + .lg\:max-w-5xl { + max-width: 64rem; + } + .lg\:shrink-0 { + flex-shrink: 0; + } + .lg\:grid-cols-2 { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + .lg\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .lg\:flex-row { + flex-direction: row; + } + .lg\:flex-wrap { + flex-wrap: wrap; + } + .lg\:items-start { + align-items: flex-start; + } + .lg\:justify-center { + justify-content: center; + } + .lg\:justify-between { + justify-content: space-between; + } + .lg\:rounded-modal-xl { + border-radius: var(--radius-modal-xl); + } + .lg\:border { + border-width: 1px; + } + .lg\:p-8 { + padding: 2rem; + } + .lg\:px-8 { + padding-left: 2rem; + padding-right: 2rem; + } + .lg\:text-right { + text-align: right; + } +} +@media (min-width: 1280px) { + .xl\:grid-cols-3 { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + .xl\:grid-cols-4 { + grid-template-columns: repeat(4, minmax(0, 1fr)); + } +} diff --git a/dist/docs/README.md b/dist/docs/README.md new file mode 100644 index 00000000..30c50a0b --- /dev/null +++ b/dist/docs/README.md @@ -0,0 +1,35 @@ +# Documentation Index + +Welcome to the bitvid documentation. This directory contains detailed architectural guides, API references, and system overviews. + +## Core Systems + +- **[Application Coordinators](./app-coordinators.md)**: Overview of the coordinator pattern used to manage app-wide state and services. +- **[Authentication Architecture](./auth-architecture.md)**: How session management, login flows, and signer integration work. +- **[Feed Engine](./feed-engine.md)**: The pipeline for fetching, filtering, scoring, and sorting video feeds. +- **[Playback & Fallback](./playback-fallback.md)**: The URL-first playback strategy with WebTorrent fallback orchestration. +- **[Watch History System](./watch-history-system.md)**: Encrypted watch history synchronization and storage. + +## Nostr Protocol + +- **[Nostr Event Schemas](./nostr-event-schemas.md)**: The definitive catalogue of all Nostr event kinds and data structures used by bitvid. +- **[DM Privacy Model](./dm-privacy-model.md)**: How Direct Messages are handled, including NIP-17 relays and privacy controls. +- **[NIP-46 Client Overview](./nip46-client-overview.md)**: Details on the NIP-46 remote signer implementation. + +## Moderation & Safety + +- **[Moderation Service](./moderation-service-overview.md)**: How content moderation, reporting, and admin lists function. +- **[Logging Strategy](./logging.md)**: Guidelines for using `devLogger` vs `userLogger` and production logging policies. + +## Design & UI + +- **[Design System](./design-system.md)**: Guide to the token-based design system and CSS architecture. +- **[Menus & Popovers](./menus.md)**: Documentation for the menu and popover system. + +## Operations + +- **[Instance Configuration](./instance-config.md)**: Guide to configuring a bitvid instance. +- **[Deployment Notes](./deployment-notes.md)**: Notes and checklists for deploying bitvid. +- **[Manual QA Checklist](./qa.md)**: The standard manual QA script for releases. + +For more details on contributing, please see [CONTRIBUTING.md](../CONTRIBUTING.md). diff --git a/dist/docs/VideoModal-overview.md b/dist/docs/VideoModal-overview.md new file mode 100644 index 00000000..d4d2fd92 --- /dev/null +++ b/dist/docs/VideoModal-overview.md @@ -0,0 +1,82 @@ +# VideoModal Component Overview + +The `VideoModal` (`js/ui/components/VideoModal.js`) is the primary UI controller for the full-screen video playback experience in bitvid. It manages the modal lifecycle, orchestrates playback, and coordinates sub-controllers for social interactions (comments, reactions, moderation). + +## Core Responsibilities + +1. **Lifecycle Management**: Handles lazy-loading of the modal HTML, DOM injection, and visibility toggling. +2. **Playback Orchestration**: Connects the video metadata to the underlying media player (via `mediaLoader` or direct video element manipulation). +3. **Social Coordination**: Instantiates and manages `CommentsController`, `ReactionsController`, `SimilarContentController`, and `ModerationController`. +4. **Accessibility**: Enforces focus trapping and ARIA attributes via `ModalAccessibility`. +5. **Global State Integration**: Updates the application's modal state (`setGlobalModalState`) to pause background feeds and handle back-button navigation. + +## Public API + +The `VideoModal` exposes a minimal public interface for the application orchestrator (`ModalManager` or `App`): + +| Method | Description | +|--------|-------------| +| `constructor(deps)` | Initializes the controller with dependencies (DOM, logger, state helpers). Does *not* touch the DOM. | +| `async load()` | Fetches `components/video-modal.html`, injects it into the DOM, and hydrates references. Safe to call multiple times (idempotent). | +| `open(video, options)` | Resets state, populates the modal with the given `video` object, and makes it visible. | +| `close()` | Hides the modal, pauses playback, clears state, and returns focus to the trigger element. | + +### Dependencies +The constructor requires a robust dependency injection object: +- `document`: The DOM document. +- `setGlobalModalState`: Function to notify the app of modal visibility changes. +- `logger`: Logging utility. +- `mediaLoader`: Service for handling media source resolution. +- `assets`, `state`, `helpers`: Configuration objects. + +## internal Architecture + +### Lazy Loading & Hydration +To improve initial page load performance, `VideoModal` does not render its markup until `load()` is called (typically on the first user interaction). +1. **Fetch**: Retrieves `components/video-modal.html`. +2. **Inject**: Appends the HTML to the `#modalContainer`. +3. **Hydrate**: Queries for all necessary DOM elements (buttons, containers, inputs) and binds event listeners. +4. **Sub-Controller Init**: Initializes `CommentsController`, `ReactionsController`, etc., passing them the fresh DOM references. + +### Sub-Controllers +The `VideoModal` acts as a parent controller, delegating specific logic to specialized classes: +- **`CommentsController`**: Manages the comment thread, composer, and fetching. +- **`ReactionsController`**: Handles likes/dislikes and reaction counts. +- **`SimilarContentController`**: Fetches and renders related videos. +- **`ModerationController`**: Manages content warnings, blurring, and reporting flows. + +## Usage Example + +```javascript +// Instantiation (usually in ModalManager) +const videoModal = new VideoModal({ + document: document, + setGlobalModalState: (key, active) => app.setModalState(key, active), + logger: logger, + mediaLoader: mediaLoader +}); + +// Initialization (lazy) +await videoModal.load(); + +// Opening +const video = { + id: "...", + title: "My Video", + pubkey: "...", + // ... other metadata +}; +videoModal.open(video, { triggerElement: clickedCard }); +``` + +## Key Invariants + +1. **Single Active Instance**: Only one video modal exists in the DOM at a time. Opening a new video replaces the content of the existing modal. +2. **Focus Management**: When open, the modal traps focus. When closed, it restores focus to the element that triggered it (via `options.triggerElement`). +3. **State Synchronization**: The `setGlobalModalState` callback MUST be called on open/close to ensure the back button works correctly and background videos pause. + +## When to Change + +- **Refactoring**: This file is extremely large (>6000 LOC). Consider extracting more logic into sub-controllers (e.g., a `MetadataController` for title/description/tags). +- **Styling**: Changes to the modal layout should be mirrored in `components/video-modal.html` and tested for responsiveness. +- **Playback Logic**: Changes to how videos load or play should likely be done in `mediaLoader` or `PlaybackService` rather than here, unless it's strictly UI-related (e.g., custom controls). diff --git a/dist/docs/app-coordinators.md b/dist/docs/app-coordinators.md new file mode 100644 index 00000000..1b5d7af0 --- /dev/null +++ b/dist/docs/app-coordinators.md @@ -0,0 +1,104 @@ +# Application Coordinator Architecture + +The `Application` class (`js/app.js`) acts as the **composition root** for bitvid. +Business logic that previously lived directly on `Application` has been extracted +into **coordinator modules** under `js/app/`. `Application` retains thin +delegator methods so that every public call-site continues to work unchanged. + +## Coordinator Modules + +| Module | File | Responsibility | +|--------|------|----------------| +| Feed | `js/app/feedCoordinator.js` | Feed registration, runtime building, refresh, video loading, URL-health helpers, feed telemetry | +| Playback | `js/app/playbackCoordinator.js` | URL-first + magnet fallback pipeline, probing, torrent status, video timestamps | +| Auth/Session | `js/app/authSessionCoordinator.js` | Signer lifecycle, profile switching, relay/block/wallet management, cleanup | +| Modal | `js/app/modalCoordinator.js` | Modal open/close, view-count subscriptions, watch-history metadata, playback logging | +| Moderation | `js/app/moderationCoordinator.js` | Moderation settings, video decoration, override/block/hide actions | + +A shared helper (`js/app/bindCoordinator.js`) binds every method returned by a +coordinator factory to the `Application` instance so that `this` works as expected. + +## Dependency Injection + +Each coordinator is a factory function that receives a `deps` object containing +every module-level dependency it needs. Coordinators **never import globals** +themselves; all references come through the closure created by `deps`: + +```javascript +export function createFeedCoordinator(deps) { + const { devLogger, nostrClient, watchHistoryService, ... } = deps; + + return { + async loadVideos(forceFetch = false) { + devLogger.log("Starting loadVideos..."); // closure var, not import + // `this` is the Application instance (bound by caller) + this.checkRelayHealthWarning(); + // ... + }, + }; +} +``` + +`Application._initCoordinators()` creates all five coordinators and injects their +dependencies from the module scope of `js/app.js`. It is called eagerly in the +constructor and idempotently from every delegator, so test harnesses that use +`Object.create(Application.prototype)` also work. + +## Delegation Pattern + +Every extracted method has a matching thin delegator on `Application`: + +```javascript +class Application { + async loadVideos(...args) { + this._initCoordinators(); + return this._feed.loadVideos(...args); + } +} +``` + +This preserves the public API surface. Callers (views, services, test harnesses) +do not need to know about coordinators. + +## Old-to-New Mapping + +| Old location (`Application` method) | New location | +|--------------------------------------|--------------| +| `registerRecentFeed`, `registerForYouFeed`, `registerKidsFeed`, `registerExploreFeed`, `registerSubscriptionsFeed`, `registerWatchHistoryFeed` | `feedCoordinator` | +| `buildForYouFeedRuntime`, `buildExploreFeedRuntime`, `buildRecentFeedRuntime`, `buildKidsFeedRuntime` | `feedCoordinator` | +| `refreshForYouFeed`, `refreshKidsFeed`, `refreshExploreFeed`, `refreshRecentFeed` | `feedCoordinator` | +| `loadVideos`, `loadForYouVideos`, `loadKidsVideos`, `loadExploreVideos`, `loadOlderVideos` | `feedCoordinator` | +| `renderVideoList`, `refreshVideoDiscussionCounts` | `feedCoordinator` | +| `checkRelayHealthWarning`, `hasOlderVersion` | `feedCoordinator` | +| Feed telemetry (`getFeedTelemetryState`, `emitFeedImpressions`, `recordFeedClick`, ...) | `feedCoordinator` | +| `playHttp`, `playViaWebTorrent`, `playVideoWithFallback` | `playbackCoordinator` | +| `playVideoByEventId`, `playVideoWithoutEvent` | `playbackCoordinator` | +| `probeUrl`, `probeUrlWithVideoElement`, `checkUrlParams` | `playbackCoordinator` | +| `autoplayModalVideo`, `startTorrentStatusMirrors` | `playbackCoordinator` | +| `buildModalTimestampPayload`, `resolveVideoPostedAt`, `ensureModalPostedTimestamp` | `playbackCoordinator` | +| `shouldDeferModeratedPlayback`, `resumePendingModeratedPlayback` | `playbackCoordinator` | +| `handleAuthLogin`, `handleAuthLogout`, `requestLogout` | `authSessionCoordinator` | +| `handleBlocksLoaded`, `handleRelaysLoaded`, `scheduleRelayUiRefresh` | `authSessionCoordinator` | +| `cleanup`, `waitForCleanup`, `clearActiveIntervals` | `authSessionCoordinator` | +| `handleProfileSwitchRequest`, `waitForIdentityRefresh`, `handleProfileLogoutRequest` | `authSessionCoordinator` | +| `handleProfileRelayOperation`, `handleProfileBlocklistMutation`, `handleProfileAdminMutation` | `authSessionCoordinator` | +| `handleProfileWalletPersist`, `handleProfileWalletTest`, `handleProfileWalletDisconnect` | `authSessionCoordinator` | +| `showModalWithPoster`, `hideModal`, `ensureVideoModalReady` | `modalCoordinator` | +| `subscribeModalViewCount`, `teardownModalViewCountSubscription` | `modalCoordinator` | +| `preparePlaybackLogging`, `teardownVideoElement` | `modalCoordinator` | +| `persistWatchHistoryMetadataForVideo`, `handleRemoveHistoryAction` | `modalCoordinator` | +| `setShareButtonState`, `getShareUrlBase` | `modalCoordinator` | +| `handleModerationSettingsChange`, `refreshVisibleModerationUi` | `moderationCoordinator` | +| `decorateVideoModeration`, `initializeModerationActionController` | `moderationCoordinator` | +| `handleModerationOverride`, `handleModerationBlock`, `handleModerationHide` | `moderationCoordinator` | +| `normalizeModerationSettings`, `getActiveModerationThresholds` | `moderationCoordinator` | + +## Adding New Methods + +When adding a method that belongs to an existing coordinator: + +1. Add the method to the coordinator's return object. +2. Add a thin delegator on `Application` that calls `this._initCoordinators()` + then delegates to the coordinator. +3. If the method uses a new module-level import, add it to the coordinator's + `deps` destructuring and pass it from `_initCoordinators()`. diff --git a/dist/docs/capacitor-native-app-plan.md b/dist/docs/capacitor-native-app-plan.md new file mode 100644 index 00000000..2dd2f6a4 --- /dev/null +++ b/dist/docs/capacitor-native-app-plan.md @@ -0,0 +1,849 @@ +# Capacitor Native App Plan + +> **Status**: Planning +> **Platforms**: Android, iOS, Windows, macOS, Linux +> **Framework**: [Capacitor](https://capacitorjs.com/) by Ionic +> **Goal**: Ship bitvid as a native app on all major platforms while keeping a single codebase with the existing web/PWA deployment. + +--- + +## Table of Contents + +1. [Why Capacitor](#why-capacitor) +2. [Architecture Overview](#architecture-overview) +3. [Repository Structure](#repository-structure) +4. [Phase 1 — Foundation](#phase-1--foundation) +5. [Phase 2 — Android & iOS](#phase-2--android--ios) +6. [Phase 3 — Desktop (Electron via Capacitor)](#phase-3--desktop-electron-via-capacitor) +7. [Phase 4 — Platform-Specific Enhancements](#phase-4--platform-specific-enhancements) +8. [Phase 5 — CI/CD for Native Builds](#phase-5--cicd-for-native-builds) +9. [Phase 6 — Testing Strategy](#phase-6--testing-strategy) +10. [Platform Considerations & Risks](#platform-considerations--risks) +11. [App Store Strategy](#app-store-strategy) +12. [Task Checklist](#task-checklist) + +--- + +## Why Capacitor + +### Fit for bitvid + +bitvid is a fully static, client-side web application. There is no backend server — all authentication, data, and state management happens in the browser via Nostr relays and WebTorrent. This makes it an ideal candidate for Capacitor, which wraps an existing web app in a native WebView shell. + +### Key reasons + +| Reason | Detail | +|--------|--------| +| **Zero rewrite** | The existing `dist/` build output drops directly into Capacitor as the web layer. No framework migration needed. | +| **Single codebase** | Web, PWA, Android, iOS, and desktop all share the same HTML/CSS/JS. Platform-specific behavior is handled via feature detection and Capacitor's plugin bridge. | +| **Progressive native access** | Start with a pure web wrapper, then incrementally add native plugins (deep links, push notifications, share targets, file system) only when needed. | +| **Mature mobile support** | Capacitor has first-class Android and iOS support with a large plugin ecosystem. | +| **Desktop via Electron** | The `@nicepkg/capacitor-electron` community plugin (or the `@nicepkg/cap-electron` plugin) lets Capacitor drive an Electron shell for Windows/macOS/Linux using the same web build. | +| **Existing PWA foundation** | bitvid already has `site.webmanifest`, a service worker (`sw.min.js`), and app icons — all of which Capacitor respects and builds on. | +| **Active ecosystem** | Large community, official Ionic backing, regular releases, good documentation. | + +### Alternatives considered + +| Framework | Why not primary | +|-----------|----------------| +| **Tauri** | Excellent for desktop (small binaries, Rust backend), but mobile support is still in beta. Could be revisited later as a desktop-only option if Electron bundle size becomes a concern. | +| **Electron standalone** | Bundles ~150MB of Chromium per platform. Capacitor+Electron gives us the same result but with a unified build pipeline across all platforms. | +| **React Native / Flutter** | Would require a complete rewrite. bitvid is vanilla JS with no component framework — porting to RN or Flutter would be a ground-up rebuild. | +| **PWA only** | Already partially implemented. Good for web-savvy users but lacks app store discoverability, has weaker iOS support (no push notifications, limited background execution), and misses users who expect a "real" app install. | + +--- + +## Architecture Overview + +``` +┌─────────────────────────────────────────────────────┐ +│ bitvid codebase │ +│ │ +│ ┌───────────┐ npm run build ┌───────────────┐ │ +│ │ Source │ ────────────────→ │ dist/ │ │ +│ │ (js/, │ │ (static web │ │ +│ │ css/, │ │ assets) │ │ +│ │ views/) │ └──────┬────────┘ │ +│ └───────────┘ │ │ +│ │ │ +│ ┌────────────────┼─────┐ │ +│ │ npx cap sync │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────┐ ┌─────┐ ┌────────┐ │ +│ │ android/│ │ ios/│ │electron/│ │ +│ │ (native │ │ │ │ │ │ +│ │ project)│ │ │ │ │ │ +│ └─────────┘ └─────┘ └────────┘ │ +│ │ +│ Deploy targets: │ +│ • Web/PWA → dist/ served via Netlify/Vercel/etc │ +│ • Android → android/ → Play Store APK/AAB │ +│ • iOS → ios/ → App Store IPA │ +│ • Desktop → electron/ → Windows/macOS/Linux │ +└─────────────────────────────────────────────────────┘ +``` + +### Data flow (unchanged) + +The native shell is purely a container. All app logic remains in the web layer: + +1. User action triggers a UI controller event handler +2. Controller invokes callback provided by `bitvidApp` +3. `bitvidApp` executes logic, communicates with Nostr relays via WebSocket +4. WebTorrent handles P2P video streaming via WebRTC data channels +5. UI updates via DOM manipulation + +The only new data path is the **Capacitor bridge** — a thin JS-to-native channel used for: +- Deep link handling (Nostr URIs, `nostr:` protocol) +- Push notification tokens (optional, future) +- Native share sheet integration +- App lifecycle events (background/foreground) +- Status bar / navigation bar styling + +--- + +## Repository Structure + +The native project directories live at the repo root alongside the existing web source. This is the standard Capacitor monorepo layout. + +``` +bitvid/ +├── android/ # NEW — Native Android project (Android Studio) +│ ├── app/ +│ │ ├── src/main/ +│ │ │ ├── AndroidManifest.xml +│ │ │ ├── java/com/bitvid/app/ +│ │ │ └── res/ +│ │ └── build.gradle +│ ├── capacitor.settings.gradle +│ └── build.gradle +├── ios/ # NEW — Native iOS project (Xcode) +│ └── App/ +│ ├── App/ +│ │ ├── AppDelegate.swift +│ │ ├── Info.plist +│ │ └── capacitor.config.json (generated) +│ ├── App.xcodeproj +│ └── Podfile +├── electron/ # NEW — Electron desktop shell +│ ├── src/ +│ │ ├── index.ts +│ │ └── preload.ts +│ ├── capacitor.config.ts +│ └── package.json +├── capacitor.config.ts # NEW — Capacitor root config +├── dist/ # Existing build output (web assets) +├── js/ # Existing source +├── css/ # Existing source +├── config/ +│ └── instance-config.js # Extended with platform detection +├── scripts/ +│ ├── build-dist.mjs # Existing web build +│ ├── build-android.mjs # NEW — Android build helper +│ ├── build-ios.mjs # NEW — iOS build helper +│ └── build-desktop.mjs # NEW — Electron build helper +├── tests/ +│ ├── unit/ # Existing +│ ├── e2e/ # Existing (web) +│ ├── visual/ # Existing +│ ├── native/ # NEW — Native-specific tests +│ │ ├── android/ +│ │ ├── ios/ +│ │ └── desktop/ +│ └── platform/ # NEW — Cross-platform behavior tests +├── .github/workflows/ +│ ├── ci.yml # Existing (web CI) +│ ├── ci-android.yml # NEW — Android build + test +│ ├── ci-ios.yml # NEW — iOS build + test +│ └── ci-desktop.yml # NEW — Electron build + test +├── package.json # Extended with native scripts +├── capacitor.config.ts # Capacitor root configuration +└── site.webmanifest # Existing PWA manifest +``` + +### What gets gitignored + +```gitignore +# Native build artifacts +android/app/build/ +android/.gradle/ +android/capacitor-cordova-android-plugins/build/ +ios/App/Pods/ +ios/App/DerivedData/ +electron/dist/ +electron/node_modules/ + +# Capacitor copies of web assets (regenerated by cap sync) +android/app/src/main/assets/public/ +ios/App/App/public/ +``` + +### What gets committed + +The native project scaffolding (`android/`, `ios/`, `electron/`) **is committed** to the repo. This is the Capacitor convention — the native projects are source code, not generated artifacts. They contain platform-specific configuration (permissions, entitlements, splash screens, icons) that must be version-controlled. + +--- + +## Phase 1 — Foundation + +**Goal**: Initialize Capacitor, get the web app running inside native shells on Android and iOS simulators, and Electron on desktop. + +### Tasks + +1. **Install Capacitor core** + ```bash + npm install @capacitor/core @capacitor/cli + ``` + +2. **Create `capacitor.config.ts`** + ```typescript + import type { CapacitorConfig } from '@capacitor/cli'; + + const config: CapacitorConfig = { + appId: 'com.bitvid.app', + appName: 'bitvid', + webDir: 'dist', + server: { + // Allow WebSocket connections to Nostr relays + allowNavigation: ['*'], + }, + plugins: { + SplashScreen: { + launchShowDuration: 2000, + backgroundColor: '#0f172a', // matches theme + }, + }, + }; + + export default config; + ``` + +3. **Add native platforms** + ```bash + npx cap add android + npx cap add ios + ``` + +4. **Update build pipeline** — extend `build-dist.mjs` or add a wrapper: + ```bash + npm run build && npx cap sync + ``` + The `cap sync` command copies `dist/` into each native project and updates native dependencies. + +5. **Add Electron support** via community plugin: + ```bash + npm install @nicepkg/capacitor-electron + npx cap add electron + ``` + +6. **Add npm scripts** + ```json + { + "scripts": { + "cap:sync": "npx cap sync", + "cap:android": "npm run build && npx cap sync android && npx cap open android", + "cap:ios": "npm run build && npx cap sync ios && npx cap open ios", + "cap:electron": "npm run build && npx cap sync electron && npx cap open electron", + "build:all": "npm run build && npx cap sync" + } + } + ``` + +7. **Verify basic functionality** + - App loads in Android emulator + - App loads in iOS simulator + - App loads in Electron window + - Nostr relay WebSocket connections work + - Theme renders correctly + - Navigation / SPA routing works + +### Platform detection helper + +Add a lightweight platform detection utility that the rest of the app can use: + +```javascript +// js/utils/platform.js +import { Capacitor } from '@capacitor/core'; + +export const platform = { + isNative: Capacitor.isNativePlatform(), + isAndroid: Capacitor.getPlatform() === 'android', + isIos: Capacitor.getPlatform() === 'ios', + isElectron: Capacitor.getPlatform() === 'electron', + isWeb: Capacitor.getPlatform() === 'web', +}; +``` + +This module is safe to import on web — `@capacitor/core` detects it's running in a browser and returns `'web'` for the platform. + +--- + +## Phase 2 — Android & iOS + +**Goal**: Production-quality mobile builds ready for app store submission. + +### Android-specific work + +1. **Permissions** in `AndroidManifest.xml`: + - `INTERNET` (already default) + - `ACCESS_NETWORK_STATE` (connectivity detection) + - `CAMERA` / `MICROPHONE` — only if video recording is added later (not needed now) + +2. **WebView configuration**: + - Enable mixed content mode (for WebSocket `wss://` alongside `https://`) + - Enable JavaScript (default in Capacitor) + - Set `webSettings.mediaPlaybackRequiresUserGesture = false` for autoplay + +3. **App icons and splash screens**: + - Use `@capacitor/splash-screen` plugin + - Generate from existing `assets/png/android-chrome-512x512.png` + - Use `cordova-res` or `@capacitor/assets` to generate all density variants + +4. **Deep links**: + - Register `nostr:` URI scheme via Android intent filters + - Register `https://bitvid.tv` domain for App Links (needs `.well-known/assetlinks.json`) + +5. **Status bar and navigation bar**: + - `@capacitor/status-bar` plugin to match the dark theme (`#0f172a`) + - Handle safe areas / notch insets via CSS `env(safe-area-inset-*)` + +### iOS-specific work + +1. **Info.plist configuration**: + - `NSAppTransportSecurity` — allow WebSocket connections + - App description strings for any permission prompts + +2. **WKWebView settings**: + - `allowsInlineMediaPlayback: true` + - `mediaTypesRequiringUserActionForPlayback: []` (enables autoplay) + - These are configurable in `capacitor.config.ts` under `ios.webContentsConfiguration` + +3. **Deep links**: + - Universal Links (needs `apple-app-site-association` on the domain) + - Custom URL scheme `bitvid://` + +4. **Safe areas**: + - iOS notch, Dynamic Island, home indicator + - CSS `env(safe-area-inset-top)` etc. — update layout in `index.html` and key UI components + +5. **App icons**: + - Generate full icon set from existing 512x512 source + - Must include 1024x1024 for App Store + +### Shared mobile work + +1. **Hardware back button** (Android): + - Handle back navigation within the SPA instead of exiting the app + - Use `@capacitor/app` plugin's `backButton` listener + +2. **App lifecycle**: + - Pause/resume WebSocket connections on app background/foreground + - Use `@capacitor/app` `appStateChange` listener + +3. **Keyboard handling**: + - Adjust layout when virtual keyboard appears (search bar, comment inputs) + - Capacitor provides `Keyboard` plugin for this + +4. **Haptic feedback** (optional): + - Light haptics on zap actions using `@capacitor/haptics` + +--- + +## Phase 3 — Desktop (Electron via Capacitor) + +**Goal**: Ship bitvid as a standalone desktop app for Windows, macOS, and Linux. + +### Approach + +Use Capacitor's Electron integration so the desktop build uses the same `dist/` web assets and the same Capacitor plugin bridge as mobile. + +### Desktop-specific work + +1. **Window configuration**: + - Default size: 1280x800 (fits well for video content) + - Minimum size: 800x600 + - Remember window position/size across launches + - Frameless window option with custom title bar (matches bitvid header) + +2. **Menu bar**: + - Minimal native menu (File, Edit, View, Help) + - Or hide native menu and use the web app's own navigation + +3. **Tray icon** (optional): + - System tray icon for background seeding (WebTorrent) + - "Minimize to tray" behavior + +4. **Auto-updater**: + - Electron's `autoUpdater` for seamless desktop updates + - Or use GitHub Releases as the update feed + +5. **Protocol handler**: + - Register `nostr:` and `bitvid:` URI schemes at OS level + +6. **Packaging**: + - Windows: NSIS installer or MSIX + - macOS: DMG + notarization + - Linux: AppImage, .deb, .rpm + +--- + +## Phase 4 — Platform-Specific Enhancements + +These are optional features that improve the native experience. Implement after core functionality is solid. + +### Native share sheet + +```javascript +import { Share } from '@capacitor/share'; + +async function shareVideo(video) { + if (platform.isNative) { + await Share.share({ + title: video.title, + text: video.description, + url: `https://bitvid.tv/#video/${video.id}`, + dialogTitle: 'Share video', + }); + } +} +``` + +### Push notifications (future) + +Nostr-based push could be implemented via: +- A lightweight push relay that watches for mentions/zaps and sends FCM/APNs +- `@capacitor/push-notifications` plugin to receive them + +This is a significant feature and should be its own planning document. + +### Offline support + +- Cache the app shell and critical assets in the service worker +- Cache recently viewed video metadata for offline browsing +- Queue zaps and reactions for when connectivity returns + +### Picture-in-picture + +- Android: native PiP mode via custom Capacitor plugin +- iOS: `AVPictureInPictureController` via the WebView's native video player +- Desktop: Electron `BrowserWindow` PiP API + +--- + +## Phase 5 — CI/CD for Native Builds + +### New CI workflows + +#### `ci-android.yml` + +```yaml +name: CI — Android + +on: + push: + branches: [main] + paths: + - 'js/**' + - 'css/**' + - 'views/**' + - 'components/**' + - 'android/**' + - 'capacitor.config.ts' + - 'package.json' + pull_request: + paths: + - 'js/**' + - 'css/**' + - 'views/**' + - 'components/**' + - 'android/**' + - 'capacitor.config.ts' + +jobs: + build-android: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: '17' + - name: Install dependencies + run: npm ci + - name: Build web assets + run: npm run build + - name: Sync Capacitor + run: npx cap sync android + - name: Build Android debug APK + working-directory: android + run: ./gradlew assembleDebug + - name: Upload APK artifact + uses: actions/upload-artifact@v4 + with: + name: bitvid-android-debug + path: android/app/build/outputs/apk/debug/app-debug.apk +``` + +#### `ci-ios.yml` + +```yaml +name: CI — iOS + +on: + push: + branches: [main] + paths: ['js/**', 'css/**', 'views/**', 'ios/**', 'capacitor.config.ts'] + pull_request: + paths: ['js/**', 'css/**', 'views/**', 'ios/**', 'capacitor.config.ts'] + +jobs: + build-ios: + runs-on: macos-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Install dependencies + run: npm ci + - name: Build web assets + run: npm run build + - name: Sync Capacitor + run: npx cap sync ios + - name: Install CocoaPods + working-directory: ios/App + run: pod install + - name: Build iOS (no sign) + run: | + xcodebuild build \ + -workspace ios/App/App.xcworkspace \ + -scheme App \ + -destination 'generic/platform=iOS Simulator' \ + CODE_SIGN_IDENTITY="" \ + CODE_SIGNING_REQUIRED=NO +``` + +#### `ci-desktop.yml` + +```yaml +name: CI — Desktop + +on: + push: + branches: [main] + paths: ['js/**', 'css/**', 'views/**', 'electron/**', 'capacitor.config.ts'] + pull_request: + paths: ['js/**', 'css/**', 'views/**', 'electron/**', 'capacitor.config.ts'] + +jobs: + build-desktop: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Install dependencies + run: npm ci + - name: Build web assets + run: npm run build + - name: Sync Capacitor + run: npx cap sync electron + - name: Build Electron + working-directory: electron + run: npm run build +``` + +### Path-filtered triggers + +Each native CI workflow uses `paths` filters so that: +- A CSS-only change triggers Android + iOS + Desktop builds (the web layer changed) +- A change to only `android/` triggers just the Android build +- Existing web CI (`ci.yml`) continues to run independently + +### CI cost management + +Native CI is more expensive than web CI: +- **iOS builds require `macos-latest` runners** (2-3x cost on GitHub Actions) +- **Android builds need JDK + Gradle** (slower startup) +- **Desktop builds run on 3 OS matrix** entries + +To manage costs: +- Only run native CI on PRs that touch relevant paths +- Cache Gradle/CocoaPods/node_modules aggressively +- Consider running iOS CI only on `main` merges (not every PR) initially +- Use GitHub Actions concurrency groups with `cancel-in-progress: true` + +--- + +## Phase 6 — Testing Strategy + +### Testing layers + +``` +┌─────────────────────────────────────────────┐ +│ Unit Tests (existing) │ ← Platform-agnostic +│ vitest — js logic, nostr, schemas, utils │ No changes needed +├─────────────────────────────────────────────┤ +│ Visual Regression (existing) │ ← Web viewport +│ Playwright — screenshot comparison │ Add mobile viewports +├─────────────────────────────────────────────┤ +│ E2E Web (existing) │ ← Browser-based +│ Playwright — user journeys in Chrome │ No changes needed +├─────────────────────────────────────────────┤ +│ E2E Mobile (NEW) │ ← Device/emulator +│ Appium or Detox — native app user flows │ +├─────────────────────────────────────────────┤ +│ Platform Smoke Tests (NEW) │ ← Quick validation +│ Per-platform build + launch + basic checks │ +├─────────────────────────────────────────────┤ +│ Cross-Platform Behavior Tests (NEW) │ ← Feature parity +│ Verify features work consistently across │ +│ web, Android, iOS, and desktop │ +└─────────────────────────────────────────────┘ +``` + +### New test categories + +#### Platform smoke tests (`tests/native/`) + +Quick checks that run after each native build: +- App launches without crash +- Main view renders +- WebSocket connection to a relay succeeds +- Video playback starts (URL source) +- Theme renders correctly (screenshot comparison) + +#### Mobile viewport visual tests + +Extend existing Playwright visual tests with mobile viewports: +```javascript +// playwright.config.ts addition +projects: [ + // existing desktop viewports... + { + name: 'Mobile Android', + use: { ...devices['Pixel 7'] }, + }, + { + name: 'Mobile iOS', + use: { ...devices['iPhone 14'] }, + }, +] +``` + +This runs in Playwright's browser emulation (not on real devices) but catches responsive layout issues early. + +#### WebView-specific E2E tests + +For testing inside the actual native WebView (not just a browser), use: +- **Android**: Espresso + WebView assertions, or Appium with WebView context switching +- **iOS**: XCUITest + WebView inspection, or Appium + +These are heavier to set up but catch WebView-specific issues (service worker behavior, WebRTC in WKWebView, etc). + +#### What to test per platform + +| Test | Web | Android | iOS | Desktop | +|------|-----|---------|-----|---------| +| Unit tests | yes | n/a | n/a | n/a | +| Visual regression (browser) | yes | mobile viewport | mobile viewport | yes | +| E2E web journeys | yes | — | — | — | +| App launches | — | yes | yes | yes | +| Relay WebSocket connects | yes | yes | yes | yes | +| Video playback (URL) | yes | yes | yes | yes | +| Video playback (WebTorrent) | yes | yes | **test carefully** | yes | +| Deep links (`nostr:`) | — | yes | yes | yes | +| Back button navigation | — | yes | — | — | +| Safe area rendering | — | — | yes | — | +| Keyboard interaction | — | yes | yes | — | +| Offline behavior | yes | yes | yes | yes | + +--- + +## Platform Considerations & Risks + +### WebTorrent on iOS (HIGH RISK) + +**Issue**: WKWebView's WebRTC support is more limited than desktop Chrome. WebTorrent relies on WebRTC data channels for peer-to-peer streaming. + +**Mitigation**: +- bitvid already has a URL-first playback fallback (`DEFAULT_PLAYBACK_SOURCE` in instance config) +- For iOS builds, default to URL-first playback: `DEFAULT_PLAYBACK_SOURCE: 'url'` +- Use platform detection to set this automatically: + ```javascript + if (platform.isIos) { + setUrlFirstEnabled(true); + } + ``` +- Test WebTorrent streaming on real iOS devices — it may work in modern iOS versions (16+), but should not be the primary path + +### Service worker in Capacitor WebView + +**Issue**: The `sw.min.js` service worker intercepts fetch requests to proxy WebTorrent stream data. Service worker support in native WebViews varies. + +**Mitigation**: +- Android: WKWebView supports service workers (API level 33+). For older Android, the URL fallback handles it. +- iOS: WKWebView supports service workers in iOS 14+, but with some caveats around scope and lifecycle. +- Test the WebTorrent streaming service worker flow specifically in native WebViews. +- If service worker is unreliable, consider a Capacitor plugin that bridges native HTTP interception as an alternative stream proxy. + +### WebSocket connectivity + +**Issue**: Native platforms may restrict background WebSocket connections. + +**Mitigation**: +- Use `@capacitor/app` lifecycle events to gracefully disconnect/reconnect: + ```javascript + App.addListener('appStateChange', ({ isActive }) => { + if (isActive) { + nostrClient.reconnect(); + } else { + nostrClient.pause(); + } + }); + ``` +- This also reduces battery drain from idle relay connections. + +### Content Security Policy + +**Issue**: Capacitor serves web assets from a local origin (`capacitor://localhost` on iOS, `https://localhost` on Android). CSP rules may need adjustment. + +**Mitigation**: +- Update `_headers` / CSP meta tags to allow the Capacitor local origin +- Allow `wss://*` for Nostr relay connections +- Allow `blob:` and `data:` for WebTorrent stream playback + +### App Store rejection risk + +See the [App Store Strategy](#app-store-strategy) section below. + +--- + +## App Store Strategy + +### Google Play Store + +**Risk level**: Low-Medium + +Google is generally more permissive. Key considerations: +- **Content rating**: Declare user-generated content (UGC) in the rating questionnaire +- **Moderation**: bitvid's existing moderation system (NIP-56 reports, NIP-51 mute lists, blur thresholds, autoplay blocking) demonstrates active content moderation +- **Crypto/payments**: Lightning/Zap functionality may trigger financial services review. Frame it as "tips" or "donations", not as a payment system. Emphasize that bitvid does not custody funds. + +### Apple App Store + +**Risk level**: Medium-High + +Apple has been unpredictable with Nostr/decentralized apps. Key considerations: +- **Guideline 4.2 (Minimum Functionality)**: The app must provide functionality beyond a "repackaged website". Native features (deep links, share sheet, haptics, PiP) help differentiate. +- **Guideline 1.2 (User Generated Content)**: Must have content reporting, blocking, and moderation. bitvid already has this. +- **Guideline 3.1.1 (In-App Purchase)**: If Lightning zaps are interpreted as digital purchases, Apple may require IAP. Mitigation: frame zaps as peer-to-peer tips external to the app (similar to how other Nostr apps handle this). +- **Review strategy**: Submit early with a clear App Review note explaining the decentralized architecture and content moderation approach. Engage with the review team proactively. + +### Desktop distribution + +**Risk level**: Low + +- **Windows**: Distribute via GitHub Releases initially. Microsoft Store submission optional. +- **macOS**: Notarize the DMG with an Apple Developer account. Distribute via GitHub Releases or the Mac App Store. +- **Linux**: AppImage on GitHub Releases. Snap Store / Flathub optional. + +--- + +## Task Checklist + +### Phase 1 — Foundation +- [ ] Install `@capacitor/core` and `@capacitor/cli` +- [ ] Create `capacitor.config.ts` with bitvid app ID and config +- [ ] Run `npx cap add android` and verify project structure +- [ ] Run `npx cap add ios` and verify project structure +- [ ] Set up Electron via community Capacitor plugin +- [ ] Add `js/utils/platform.js` platform detection utility +- [ ] Update `package.json` with Capacitor scripts (`cap:sync`, `cap:android`, `cap:ios`, `cap:electron`) +- [ ] Update `.gitignore` for native build artifacts +- [ ] Verify web app loads in Android emulator +- [ ] Verify web app loads in iOS simulator +- [ ] Verify web app loads in Electron window +- [ ] Verify Nostr relay connections work on all platforms +- [ ] Document local development setup for native builds + +### Phase 2 — Android & iOS +- [ ] Configure Android permissions in `AndroidManifest.xml` +- [ ] Configure iOS `Info.plist` settings +- [ ] Generate app icons for all densities (Android + iOS) +- [ ] Generate splash screens +- [ ] Implement safe area CSS for iOS notch / Dynamic Island +- [ ] Add `@capacitor/status-bar` and theme it to match bitvid +- [ ] Add `@capacitor/app` for lifecycle events (background/foreground) +- [ ] Implement hardware back button handling (Android) +- [ ] Set up deep link handling for `nostr:` URIs +- [ ] Configure WebView settings for media autoplay +- [ ] Test video playback (URL source) on both platforms +- [ ] Test video playback (WebTorrent) on both platforms +- [ ] Test service worker behavior in native WebViews +- [ ] Set iOS default to URL-first playback if WebTorrent is unreliable + +### Phase 3 — Desktop +- [ ] Configure Electron window defaults (size, min size, position memory) +- [ ] Set up native menu bar or hide it +- [ ] Register `nostr:` protocol handler at OS level +- [ ] Configure packaging (NSIS/DMG/AppImage) +- [ ] Test on Windows, macOS, and Linux +- [ ] Set up auto-updater with GitHub Releases feed + +### Phase 4 — Platform Enhancements +- [ ] Implement native share sheet integration +- [ ] Add `@capacitor/keyboard` for mobile input handling +- [ ] Explore picture-in-picture on each platform +- [ ] Add haptic feedback for zap actions (optional) +- [ ] Implement app shell caching in service worker for offline support + +### Phase 5 — CI/CD +- [ ] Create `ci-android.yml` workflow +- [ ] Create `ci-ios.yml` workflow +- [ ] Create `ci-desktop.yml` workflow (3-OS matrix) +- [ ] Add path filters to limit when native CI runs +- [ ] Set up artifact uploads for debug builds +- [ ] Configure caching (Gradle, CocoaPods, node_modules) +- [ ] Add concurrency groups to cancel stale runs +- [ ] Document release signing process (keystores, certificates, notarization) + +### Phase 6 — Testing +- [ ] Add mobile viewport projects to Playwright config +- [ ] Create platform smoke test suite (`tests/native/`) +- [ ] Set up Android emulator tests in CI +- [ ] Set up iOS simulator tests in CI +- [ ] Test WebTorrent streaming in native WebViews on real devices +- [ ] Test service worker behavior across platforms +- [ ] Test deep link handling on all platforms +- [ ] Create cross-platform feature parity test matrix +- [ ] Document known platform-specific limitations in `KNOWN_ISSUES.md` + +### App Store Submission +- [ ] Create Google Play developer account +- [ ] Prepare Play Store listing (screenshots, description, content rating) +- [ ] Submit Android app for review +- [ ] Create Apple Developer account (if not existing) +- [ ] Prepare App Store listing (screenshots, description, review notes) +- [ ] Submit iOS app for review +- [ ] Set up GitHub Releases for desktop distribution +- [ ] Notarize macOS DMG + +--- + +## Related Documentation + +- [Playback Fallback Architecture](playback-fallback.md) — URL-first strategy that mitigates WebTorrent issues on mobile +- [Instance Configuration](instance-config.md) — Platform-specific config overrides +- [WebTorrent Architecture](webtorrent-architecture.md) — Service worker streaming details +- [Moderation Service Overview](moderation-service-overview.md) — Content moderation (relevant for app store review) diff --git a/dist/docs/events-cache-store-overview.md b/dist/docs/events-cache-store-overview.md new file mode 100644 index 00000000..dd9e5a75 --- /dev/null +++ b/dist/docs/events-cache-store-overview.md @@ -0,0 +1,96 @@ +# EventsCacheStore Overview + +The `EventsCacheStore` is a specialized persistence layer designed to handle the application's critical state: thousands of video events and their deletion status (tombstones). It uses **IndexedDB** as the primary storage backend, falling back to `localStorage` (via `PersistenceManager`) only if IDB is unavailable. + +## 1. Problem Statement + +Nostr clients must handle high-volume event streams. Storing every event naively to disk on every change causes: +- **Write Trashing**: Frequent, redundant writes degrade performance and battery life. +- **I/O Blocking**: Large JSON serializations on the main thread cause UI jank. +- **Startup Latency**: Reading thousands of small files or one giant blob is slow. + +## 2. Architecture: Incremental Persistence + +`EventsCacheStore` solves this with a **Differential State Snapshot** approach. + +### Key Concepts + +1. **Memory Fingerprints**: + - The store maintains a `Map