From 8daa85ff79626b20740755ca0f97cc47fe585077 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 15 Sep 2026 11:28:19 +0200 Subject: [PATCH 1/5] Mirror openvidu.io's w-25/w-50 utility classes in the synced tutorials openvidu.io replaced the image width inline styles in the shared tutorial pages with classes; the same edit here keeps the pairs identical and adds the two classes to extra.css. --- docs/stylesheets/extra.css | 8 ++++++++ docs/tutorials/application-client/android.md | 2 +- docs/tutorials/application-client/ionic.md | 2 +- docs/tutorials/application-client/ios.md | 4 ++-- shared/tutorials/application-client/android.md | 6 +++--- shared/tutorials/application-client/ionic.md | 6 +++--- shared/tutorials/application-client/ios.md | 6 +++--- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 9045bb3..0739eb4 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -281,6 +281,14 @@ div[class*="grid-"]:has(> img) { text-align: center; } +.w-25 { + width: 25%; +} + +.w-50 { + width: 50%; +} + .nowrap { white-space: nowrap; } diff --git a/docs/tutorials/application-client/android.md b/docs/tutorials/application-client/android.md index bb43cd2..c118397 100644 --- a/docs/tutorials/application-client/android.md +++ b/docs/tutorials/application-client/android.md @@ -140,7 +140,7 @@ You should configure these URLs according to your deployment settings. In case y If these URLs are left empty, the user will be prompted to enter the URLs when the application starts. This configuration is managed in the `ConfigureUrlsActivity.kt` file: -![URL configuration of the Android tutorial app](../../assets/images/tutorials/application-client/configure-urls-android.png){ loading=lazy style="width: 25%" } +![URL configuration of the Android tutorial app](../../assets/images/tutorials/application-client/configure-urls-android.png){ .w-25 loading=lazy } When the user clicks the `Save` button, the `onSaveUrls()` method is called, which saves the URLs in the `Urls` object and finishes the activity, returning to the MainActivity: diff --git a/docs/tutorials/application-client/ionic.md b/docs/tutorials/application-client/ionic.md index cfd976f..e0f4ac4 100644 --- a/docs/tutorials/application-client/ionic.md +++ b/docs/tutorials/application-client/ionic.md @@ -184,7 +184,7 @@ In case you are [running OpenVidu locally](#run-openvidu-locally) and launching If you leave them empty and app is launched in a mobile device, the user will be prompted to enter the URLs when the application starts: -![URL configuration of the Ionic tutorial app](../../assets/images/tutorials/application-client/configure-urls-ionic.png){ loading=lazy style="width: 25%" } +![URL configuration of the Ionic tutorial app](../../assets/images/tutorials/application-client/configure-urls-ionic.png){ .w-25 loading=lazy } --- diff --git a/docs/tutorials/application-client/ios.md b/docs/tutorials/application-client/ios.md index 532eef4..390426a 100644 --- a/docs/tutorials/application-client/ios.md +++ b/docs/tutorials/application-client/ios.md @@ -136,7 +136,7 @@ You should configure these URLs according to your deployment settings. If you ar If these URLs are left empty, the user will be prompted to enter them when the application starts. This configuration is managed in the `ConfigureUrlsView.swift` file: -![URL configuration of the iOS tutorial app](../../assets/images/tutorials/application-client/configure-urls-ios.png){ loading=lazy style="width: 25%" } +![URL configuration of the iOS tutorial app](../../assets/images/tutorials/application-client/configure-urls-ios.png){ .w-25 loading=lazy } When the user clicks the `Save` button, the `LKButton` action triggers the validation and saves the URLs into the `AppContext` and `RoomContext`. The `ConfigureUrlsView` handles this logic: @@ -167,7 +167,7 @@ In this code snippet, the `isValidURL` function checks the validity of the URLs. Before joining a room, the `ConnectView.swift` defines the view for the connection screen. It includes a logo, text fields for participant name and room name, and buttons for joining the room and resetting URLs. -![Join screen of the iOS tutorial app](../../assets/images/tutorials/application-client/join-ios.png){ loading=lazy style="width: 25%" } +![Join screen of the iOS tutorial app](../../assets/images/tutorials/application-client/join-ios.png){ .w-25 loading=lazy } After define the participant and room name, the user can click the `Join` button to connect to the room. This action triggers the `connectToRoom` method asynchronously: diff --git a/shared/tutorials/application-client/android.md b/shared/tutorials/application-client/android.md index ba2f326..5c8717d 100644 --- a/shared/tutorials/application-client/android.md +++ b/shared/tutorials/application-client/android.md @@ -6,7 +6,7 @@ To run the client application tutorial, you need [Android Studio :fontawesome-so The application will initiate as a native Android program. Once the application is opened, you should see a screen like this: -![URL configuration of the Android tutorial app](/assets/images/tutorials/application-client/configure-urls-android.png){ loading=lazy style="width: 25%" } +![URL configuration of the Android tutorial app](/assets/images/tutorials/application-client/configure-urls-android.png){ .w-25 loading=lazy } This screen allows you to configure the URLs of the application server and the LiveKit server. You need to set them up for requesting tokens to your application server and connecting to the LiveKit server. @@ -19,11 +19,11 @@ Once you have configured the URLs, you can join a video call room by providing a /// html | div.grid-container /// html | div.grid-50.text-center -![Join screen of the Android tutorial app](/assets/images/tutorials/application-client/join-android.png){ loading=lazy style="width: 50%" } +![Join screen of the Android tutorial app](/assets/images/tutorials/application-client/join-android.png){ .w-50 loading=lazy } /// /// html | div.grid-50.text-center -![Video call room of the Android tutorial app](/assets/images/tutorials/application-client/room-android.png){ loading=lazy style="width: 50%" } +![Video call room of the Android tutorial app](/assets/images/tutorials/application-client/room-android.png){ .w-50 loading=lazy } /// /// diff --git a/shared/tutorials/application-client/ionic.md b/shared/tutorials/application-client/ionic.md index 2ffd880..5b9143e 100644 --- a/shared/tutorials/application-client/ionic.md +++ b/shared/tutorials/application-client/ionic.md @@ -84,7 +84,7 @@ To run the client application tutorial, you need [Node.js :fontawesome-solid-ext Once the mobile device has been selected, the script will launch the application on the device and you will see a screen like this: - ![URL configuration of the Ionic tutorial app](/assets/images/tutorials/application-client/configure-urls-ionic.png){ loading=lazy style="width: 25%" } + ![URL configuration of the Ionic tutorial app](/assets/images/tutorials/application-client/configure-urls-ionic.png){ .w-25 loading=lazy } This screen allows you to configure the URLs of the application server and the LiveKit server. You need to set them up for requesting tokens to your application server and connecting to the LiveKit server. @@ -93,11 +93,11 @@ To run the client application tutorial, you need [Node.js :fontawesome-solid-ext /// html | div.grid-container /// html | div.grid-50.text-center - ![Join screen of the Ionic tutorial app on a mobile device](/assets/images/tutorials/application-client/join-ionic-device.png){ loading=lazy style="width: 50%" } + ![Join screen of the Ionic tutorial app on a mobile device](/assets/images/tutorials/application-client/join-ionic-device.png){ .w-50 loading=lazy } /// /// html | div.grid-50.text-center - ![Video call room of the Ionic tutorial app on a mobile device](/assets/images/tutorials/application-client/room-ionic-device.png){ loading=lazy style="width: 50%" } + ![Video call room of the Ionic tutorial app on a mobile device](/assets/images/tutorials/application-client/room-ionic-device.png){ .w-50 loading=lazy } /// /// diff --git a/shared/tutorials/application-client/ios.md b/shared/tutorials/application-client/ios.md index a8435a3..e160fab 100644 --- a/shared/tutorials/application-client/ios.md +++ b/shared/tutorials/application-client/ios.md @@ -12,7 +12,7 @@ If you encounter code signing issues, make sure you change the **Team** and **bu The application will initiate as a native iOS application. Once the app is opened, you should see a screen like this: -![URL configuration of the iOS tutorial app](/assets/images/tutorials/application-client/configure-urls-ios.png){ loading=lazy style="width: 25%" } +![URL configuration of the iOS tutorial app](/assets/images/tutorials/application-client/configure-urls-ios.png){ .w-25 loading=lazy } This screen allows you to configure the URLs of the application server and the LiveKit server. You need to set them up for requesting tokens to your application server and connecting to the LiveKit server. @@ -25,11 +25,11 @@ Once you have configured the URLs, you can join a video call room by providing a /// html | div.grid-container /// html | div.grid-50.text-center -![Join screen of the iOS tutorial app](/assets/images/tutorials/application-client/join-ios.png){ loading=lazy style="width: 50%" } +![Join screen of the iOS tutorial app](/assets/images/tutorials/application-client/join-ios.png){ .w-50 loading=lazy } /// /// html | div.grid-50.text-center -![Video call room of the iOS tutorial app](/assets/images/tutorials/application-client/room-ios.png){ loading=lazy style="width: 50%" } +![Video call room of the iOS tutorial app](/assets/images/tutorials/application-client/room-ios.png){ .w-50 loading=lazy } /// /// From f3d0c11c30a1fa0b94cccbb6385ce0a9577db7de Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 15 Sep 2026 11:51:50 +0200 Subject: [PATCH 2/5] Restore the complete unsemantic-grid.css, the same file openvidu.io ships The two sites now share one grid stylesheet byte for byte instead of two different hand-cut subsets. --- docs/stylesheets/unsemantic-grid.css | 1473 +++++++++++++++++++++++++- 1 file changed, 1422 insertions(+), 51 deletions(-) diff --git a/docs/stylesheets/unsemantic-grid.css b/docs/stylesheets/unsemantic-grid.css index 4fad028..cda947f 100644 --- a/docs/stylesheets/unsemantic-grid.css +++ b/docs/stylesheets/unsemantic-grid.css @@ -1,36 +1,91 @@ -/* Float-based column grid: the unsemantic-grid subset this site uses — the - container and the 8 cell classes, as found by scanning every page and - template for the classes this file defines. Every rule below is the - original's, byte for byte; only selectors naming a class nothing uses were - dropped (~300 of them: push/pull/prefix/suffix, `.clear`, the `hide-on-*` - helpers and the unused widths). Subset it, don't rewrite it. - Contract: mobile <960px (mobile-grid-*), tablet 960-1219px (tablet-grid-*), - desktop >=1220px (grid-*). */ - +/* Unsemantic grid (nathansmith/unsemantic), the complete build with this site's + breakpoints: mobile <960px (mobile-grid-*), tablet 960-1219px (tablet-grid-*), + desktop >=1220px (grid-*). Kept whole so any of its classes can be used without + editing this file. */ @media (max-width: 400px) { @-ms-viewport { width: 320px; } } +.clear { + clear: both; + display: block; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; +} -.grid-container:before, -.mobile-grid-50:before, -.mobile-grid-100:before, -.tablet-grid-50:before, -.grid-15:before, -.grid-20:before, -.grid-25:before, -.grid-50:before, -.grid-100:before, +.grid-container:before, .mobile-grid-5:before, .mobile-grid-10:before, .mobile-grid-15:before, .mobile-grid-20:before, .mobile-grid-25:before, .mobile-grid-30:before, .mobile-grid-35:before, .mobile-grid-40:before, .mobile-grid-45:before, .mobile-grid-50:before, .mobile-grid-55:before, .mobile-grid-60:before, .mobile-grid-65:before, .mobile-grid-70:before, .mobile-grid-75:before, .mobile-grid-80:before, .mobile-grid-85:before, .mobile-grid-90:before, .mobile-grid-95:before, .mobile-grid-100:before, .mobile-grid-33:before, .mobile-grid-66:before, .tablet-grid-5:before, .tablet-grid-10:before, .tablet-grid-15:before, .tablet-grid-20:before, .tablet-grid-25:before, .tablet-grid-30:before, .tablet-grid-35:before, .tablet-grid-40:before, .tablet-grid-45:before, .tablet-grid-50:before, .tablet-grid-55:before, .tablet-grid-60:before, .tablet-grid-65:before, .tablet-grid-70:before, .tablet-grid-75:before, .tablet-grid-80:before, .tablet-grid-85:before, .tablet-grid-90:before, .tablet-grid-95:before, .tablet-grid-100:before, .tablet-grid-33:before, .tablet-grid-66:before, .grid-5:before, .grid-10:before, .grid-15:before, .grid-20:before, .grid-25:before, .grid-30:before, .grid-35:before, .grid-40:before, .grid-45:before, .grid-50:before, .grid-55:before, .grid-60:before, .grid-65:before, .grid-70:before, .grid-75:before, .grid-80:before, .grid-85:before, .grid-90:before, .grid-95:before, .grid-100:before, .grid-33:before, .grid-66:before, .grid-offset:before, .clearfix:before, .grid-container:after, +.mobile-grid-5:after, +.mobile-grid-10:after, +.mobile-grid-15:after, +.mobile-grid-20:after, +.mobile-grid-25:after, +.mobile-grid-30:after, +.mobile-grid-35:after, +.mobile-grid-40:after, +.mobile-grid-45:after, .mobile-grid-50:after, +.mobile-grid-55:after, +.mobile-grid-60:after, +.mobile-grid-65:after, +.mobile-grid-70:after, +.mobile-grid-75:after, +.mobile-grid-80:after, +.mobile-grid-85:after, +.mobile-grid-90:after, +.mobile-grid-95:after, .mobile-grid-100:after, +.mobile-grid-33:after, +.mobile-grid-66:after, +.tablet-grid-5:after, +.tablet-grid-10:after, +.tablet-grid-15:after, +.tablet-grid-20:after, +.tablet-grid-25:after, +.tablet-grid-30:after, +.tablet-grid-35:after, +.tablet-grid-40:after, +.tablet-grid-45:after, .tablet-grid-50:after, +.tablet-grid-55:after, +.tablet-grid-60:after, +.tablet-grid-65:after, +.tablet-grid-70:after, +.tablet-grid-75:after, +.tablet-grid-80:after, +.tablet-grid-85:after, +.tablet-grid-90:after, +.tablet-grid-95:after, +.tablet-grid-100:after, +.tablet-grid-33:after, +.tablet-grid-66:after, +.grid-5:after, +.grid-10:after, .grid-15:after, .grid-20:after, .grid-25:after, +.grid-30:after, +.grid-35:after, +.grid-40:after, +.grid-45:after, .grid-50:after, -.grid-100:after { +.grid-55:after, +.grid-60:after, +.grid-65:after, +.grid-70:after, +.grid-75:after, +.grid-80:after, +.grid-85:after, +.grid-90:after, +.grid-95:after, +.grid-100:after, +.grid-33:after, +.grid-66:after, +.grid-offset:after, +.clearfix:after { content: "."; display: block; overflow: hidden; @@ -41,15 +96,7 @@ height: 0; } -.grid-container:after, -.mobile-grid-50:after, -.mobile-grid-100:after, -.tablet-grid-50:after, -.grid-15:after, -.grid-20:after, -.grid-25:after, -.grid-50:after, -.grid-100:after { +.grid-container:after, .mobile-grid-5:after, .mobile-grid-10:after, .mobile-grid-15:after, .mobile-grid-20:after, .mobile-grid-25:after, .mobile-grid-30:after, .mobile-grid-35:after, .mobile-grid-40:after, .mobile-grid-45:after, .mobile-grid-50:after, .mobile-grid-55:after, .mobile-grid-60:after, .mobile-grid-65:after, .mobile-grid-70:after, .mobile-grid-75:after, .mobile-grid-80:after, .mobile-grid-85:after, .mobile-grid-90:after, .mobile-grid-95:after, .mobile-grid-100:after, .mobile-grid-33:after, .mobile-grid-66:after, .tablet-grid-5:after, .tablet-grid-10:after, .tablet-grid-15:after, .tablet-grid-20:after, .tablet-grid-25:after, .tablet-grid-30:after, .tablet-grid-35:after, .tablet-grid-40:after, .tablet-grid-45:after, .tablet-grid-50:after, .tablet-grid-55:after, .tablet-grid-60:after, .tablet-grid-65:after, .tablet-grid-70:after, .tablet-grid-75:after, .tablet-grid-80:after, .tablet-grid-85:after, .tablet-grid-90:after, .tablet-grid-95:after, .tablet-grid-100:after, .tablet-grid-33:after, .tablet-grid-66:after, .grid-5:after, .grid-10:after, .grid-15:after, .grid-20:after, .grid-25:after, .grid-30:after, .grid-35:after, .grid-40:after, .grid-45:after, .grid-50:after, .grid-55:after, .grid-60:after, .grid-65:after, .grid-70:after, .grid-75:after, .grid-80:after, .grid-85:after, .grid-90:after, .grid-95:after, .grid-100:after, .grid-33:after, .grid-66:after, .grid-offset:after, .clearfix:after { clear: both; } @@ -61,14 +108,7 @@ padding-right: 10px; } -.mobile-grid-50, -.mobile-grid-100, -.tablet-grid-50, -.grid-15, -.grid-20, -.grid-25, -.grid-50, -.grid-100 { +.mobile-grid-5, .mobile-grid-10, .mobile-grid-15, .mobile-grid-20, .mobile-grid-25, .mobile-grid-30, .mobile-grid-35, .mobile-grid-40, .mobile-grid-45, .mobile-grid-50, .mobile-grid-55, .mobile-grid-60, .mobile-grid-65, .mobile-grid-70, .mobile-grid-75, .mobile-grid-80, .mobile-grid-85, .mobile-grid-90, .mobile-grid-95, .mobile-grid-100, .mobile-grid-33, .mobile-grid-66, .tablet-grid-5, .tablet-grid-10, .tablet-grid-15, .tablet-grid-20, .tablet-grid-25, .tablet-grid-30, .tablet-grid-35, .tablet-grid-40, .tablet-grid-45, .tablet-grid-50, .tablet-grid-55, .tablet-grid-60, .tablet-grid-65, .tablet-grid-70, .tablet-grid-75, .tablet-grid-80, .tablet-grid-85, .tablet-grid-90, .tablet-grid-95, .tablet-grid-100, .tablet-grid-33, .tablet-grid-66, .grid-5, .grid-10, .grid-15, .grid-20, .grid-25, .grid-30, .grid-35, .grid-40, .grid-45, .grid-50, .grid-55, .grid-60, .grid-65, .grid-70, .grid-75, .grid-80, .grid-85, .grid-90, .grid-95, .grid-100, .grid-33, .grid-66 { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; @@ -76,46 +116,1377 @@ padding-right: 10px; } +.grid-parent { + padding-left: 0; + padding-right: 0; +} + +.grid-offset { + clear: both; + margin-left: -10px; + margin-right: -10px; +} + @media (max-width: 959px) { - .mobile-grid-50 { + .mobile-push-5, .mobile-pull-5, .mobile-push-10, .mobile-pull-10, .mobile-push-15, .mobile-pull-15, .mobile-push-20, .mobile-pull-20, .mobile-push-25, .mobile-pull-25, .mobile-push-30, .mobile-pull-30, .mobile-push-35, .mobile-pull-35, .mobile-push-40, .mobile-pull-40, .mobile-push-45, .mobile-pull-45, .mobile-push-50, .mobile-pull-50, .mobile-push-55, .mobile-pull-55, .mobile-push-60, .mobile-pull-60, .mobile-push-65, .mobile-pull-65, .mobile-push-70, .mobile-pull-70, .mobile-push-75, .mobile-pull-75, .mobile-push-80, .mobile-pull-80, .mobile-push-85, .mobile-pull-85, .mobile-push-90, .mobile-pull-90, .mobile-push-95, .mobile-pull-95, .mobile-push-33, .mobile-pull-33, .mobile-push-66, .mobile-pull-66 { + position: relative; + } + + .hide-on-mobile { + display: none !important; + } + + .mobile-grid-5 { float: left; - width: 50%; + width: 5%; } - .mobile-grid-100 { - clear: both; - width: 100%; + .mobile-prefix-5 { + margin-left: 5%; } -} -@media (min-width: 960px) and (max-width: 1219px) { - .tablet-grid-50 { + .mobile-suffix-5 { + margin-right: 5%; + } + + .mobile-push-5 { + left: 5%; + } + + .mobile-pull-5 { + left: -5%; + } + + .mobile-grid-10 { float: left; - width: 50%; + width: 10%; } -} -@media (min-width: 1220px) { - .grid-15 { + .mobile-prefix-10 { + margin-left: 10%; + } + + .mobile-suffix-10 { + margin-right: 10%; + } + + .mobile-push-10 { + left: 10%; + } + + .mobile-pull-10 { + left: -10%; + } + + .mobile-grid-15 { float: left; width: 15%; } - .grid-20 { + .mobile-prefix-15 { + margin-left: 15%; + } + + .mobile-suffix-15 { + margin-right: 15%; + } + + .mobile-push-15 { + left: 15%; + } + + .mobile-pull-15 { + left: -15%; + } + + .mobile-grid-20 { float: left; width: 20%; } - .grid-25 { + .mobile-prefix-20 { + margin-left: 20%; + } + + .mobile-suffix-20 { + margin-right: 20%; + } + + .mobile-push-20 { + left: 20%; + } + + .mobile-pull-20 { + left: -20%; + } + + .mobile-grid-25 { float: left; width: 25%; } - .grid-50 { + .mobile-prefix-25 { + margin-left: 25%; + } + + .mobile-suffix-25 { + margin-right: 25%; + } + + .mobile-push-25 { + left: 25%; + } + + .mobile-pull-25 { + left: -25%; + } + + .mobile-grid-30 { + float: left; + width: 30%; + } + + .mobile-prefix-30 { + margin-left: 30%; + } + + .mobile-suffix-30 { + margin-right: 30%; + } + + .mobile-push-30 { + left: 30%; + } + + .mobile-pull-30 { + left: -30%; + } + + .mobile-grid-35 { + float: left; + width: 35%; + } + + .mobile-prefix-35 { + margin-left: 35%; + } + + .mobile-suffix-35 { + margin-right: 35%; + } + + .mobile-push-35 { + left: 35%; + } + + .mobile-pull-35 { + left: -35%; + } + + .mobile-grid-40 { + float: left; + width: 40%; + } + + .mobile-prefix-40 { + margin-left: 40%; + } + + .mobile-suffix-40 { + margin-right: 40%; + } + + .mobile-push-40 { + left: 40%; + } + + .mobile-pull-40 { + left: -40%; + } + + .mobile-grid-45 { + float: left; + width: 45%; + } + + .mobile-prefix-45 { + margin-left: 45%; + } + + .mobile-suffix-45 { + margin-right: 45%; + } + + .mobile-push-45 { + left: 45%; + } + + .mobile-pull-45 { + left: -45%; + } + + .mobile-grid-50 { float: left; width: 50%; } + .mobile-prefix-50 { + margin-left: 50%; + } + + .mobile-suffix-50 { + margin-right: 50%; + } + + .mobile-push-50 { + left: 50%; + } + + .mobile-pull-50 { + left: -50%; + } + + .mobile-grid-55 { + float: left; + width: 55%; + } + + .mobile-prefix-55 { + margin-left: 55%; + } + + .mobile-suffix-55 { + margin-right: 55%; + } + + .mobile-push-55 { + left: 55%; + } + + .mobile-pull-55 { + left: -55%; + } + + .mobile-grid-60 { + float: left; + width: 60%; + } + + .mobile-prefix-60 { + margin-left: 60%; + } + + .mobile-suffix-60 { + margin-right: 60%; + } + + .mobile-push-60 { + left: 60%; + } + + .mobile-pull-60 { + left: -60%; + } + + .mobile-grid-65 { + float: left; + width: 65%; + } + + .mobile-prefix-65 { + margin-left: 65%; + } + + .mobile-suffix-65 { + margin-right: 65%; + } + + .mobile-push-65 { + left: 65%; + } + + .mobile-pull-65 { + left: -65%; + } + + .mobile-grid-70 { + float: left; + width: 70%; + } + + .mobile-prefix-70 { + margin-left: 70%; + } + + .mobile-suffix-70 { + margin-right: 70%; + } + + .mobile-push-70 { + left: 70%; + } + + .mobile-pull-70 { + left: -70%; + } + + .mobile-grid-75 { + float: left; + width: 75%; + } + + .mobile-prefix-75 { + margin-left: 75%; + } + + .mobile-suffix-75 { + margin-right: 75%; + } + + .mobile-push-75 { + left: 75%; + } + + .mobile-pull-75 { + left: -75%; + } + + .mobile-grid-80 { + float: left; + width: 80%; + } + + .mobile-prefix-80 { + margin-left: 80%; + } + + .mobile-suffix-80 { + margin-right: 80%; + } + + .mobile-push-80 { + left: 80%; + } + + .mobile-pull-80 { + left: -80%; + } + + .mobile-grid-85 { + float: left; + width: 85%; + } + + .mobile-prefix-85 { + margin-left: 85%; + } + + .mobile-suffix-85 { + margin-right: 85%; + } + + .mobile-push-85 { + left: 85%; + } + + .mobile-pull-85 { + left: -85%; + } + + .mobile-grid-90 { + float: left; + width: 90%; + } + + .mobile-prefix-90 { + margin-left: 90%; + } + + .mobile-suffix-90 { + margin-right: 90%; + } + + .mobile-push-90 { + left: 90%; + } + + .mobile-pull-90 { + left: -90%; + } + + .mobile-grid-95 { + float: left; + width: 95%; + } + + .mobile-prefix-95 { + margin-left: 95%; + } + + .mobile-suffix-95 { + margin-right: 95%; + } + + .mobile-push-95 { + left: 95%; + } + + .mobile-pull-95 { + left: -95%; + } + + .mobile-grid-33 { + float: left; + width: 33.33333%; + } + + .mobile-prefix-33 { + margin-left: 33.33333%; + } + + .mobile-suffix-33 { + margin-right: 33.33333%; + } + + .mobile-push-33 { + left: 33.33333%; + } + + .mobile-pull-33 { + left: -33.33333%; + } + + .mobile-grid-66 { + float: left; + width: 66.66667%; + } + + .mobile-prefix-66 { + margin-left: 66.66667%; + } + + .mobile-suffix-66 { + margin-right: 66.66667%; + } + + .mobile-push-66 { + left: 66.66667%; + } + + .mobile-pull-66 { + left: -66.66667%; + } + + .mobile-grid-100 { + clear: both; + width: 100%; + } +} +@media (min-width: 960px) and (max-width: 1219px) { + .tablet-push-5, .tablet-pull-5, .tablet-push-10, .tablet-pull-10, .tablet-push-15, .tablet-pull-15, .tablet-push-20, .tablet-pull-20, .tablet-push-25, .tablet-pull-25, .tablet-push-30, .tablet-pull-30, .tablet-push-35, .tablet-pull-35, .tablet-push-40, .tablet-pull-40, .tablet-push-45, .tablet-pull-45, .tablet-push-50, .tablet-pull-50, .tablet-push-55, .tablet-pull-55, .tablet-push-60, .tablet-pull-60, .tablet-push-65, .tablet-pull-65, .tablet-push-70, .tablet-pull-70, .tablet-push-75, .tablet-pull-75, .tablet-push-80, .tablet-pull-80, .tablet-push-85, .tablet-pull-85, .tablet-push-90, .tablet-pull-90, .tablet-push-95, .tablet-pull-95, .tablet-push-33, .tablet-pull-33, .tablet-push-66, .tablet-pull-66 { + position: relative; + } + + .hide-on-tablet { + display: none !important; + } + + .tablet-grid-5 { + float: left; + width: 5%; + } + + .tablet-prefix-5 { + margin-left: 5%; + } + + .tablet-suffix-5 { + margin-right: 5%; + } + + .tablet-push-5 { + left: 5%; + } + + .tablet-pull-5 { + left: -5%; + } + + .tablet-grid-10 { + float: left; + width: 10%; + } + + .tablet-prefix-10 { + margin-left: 10%; + } + + .tablet-suffix-10 { + margin-right: 10%; + } + + .tablet-push-10 { + left: 10%; + } + + .tablet-pull-10 { + left: -10%; + } + + .tablet-grid-15 { + float: left; + width: 15%; + } + + .tablet-prefix-15 { + margin-left: 15%; + } + + .tablet-suffix-15 { + margin-right: 15%; + } + + .tablet-push-15 { + left: 15%; + } + + .tablet-pull-15 { + left: -15%; + } + + .tablet-grid-20 { + float: left; + width: 20%; + } + + .tablet-prefix-20 { + margin-left: 20%; + } + + .tablet-suffix-20 { + margin-right: 20%; + } + + .tablet-push-20 { + left: 20%; + } + + .tablet-pull-20 { + left: -20%; + } + + .tablet-grid-25 { + float: left; + width: 25%; + } + + .tablet-prefix-25 { + margin-left: 25%; + } + + .tablet-suffix-25 { + margin-right: 25%; + } + + .tablet-push-25 { + left: 25%; + } + + .tablet-pull-25 { + left: -25%; + } + + .tablet-grid-30 { + float: left; + width: 30%; + } + + .tablet-prefix-30 { + margin-left: 30%; + } + + .tablet-suffix-30 { + margin-right: 30%; + } + + .tablet-push-30 { + left: 30%; + } + + .tablet-pull-30 { + left: -30%; + } + + .tablet-grid-35 { + float: left; + width: 35%; + } + + .tablet-prefix-35 { + margin-left: 35%; + } + + .tablet-suffix-35 { + margin-right: 35%; + } + + .tablet-push-35 { + left: 35%; + } + + .tablet-pull-35 { + left: -35%; + } + + .tablet-grid-40 { + float: left; + width: 40%; + } + + .tablet-prefix-40 { + margin-left: 40%; + } + + .tablet-suffix-40 { + margin-right: 40%; + } + + .tablet-push-40 { + left: 40%; + } + + .tablet-pull-40 { + left: -40%; + } + + .tablet-grid-45 { + float: left; + width: 45%; + } + + .tablet-prefix-45 { + margin-left: 45%; + } + + .tablet-suffix-45 { + margin-right: 45%; + } + + .tablet-push-45 { + left: 45%; + } + + .tablet-pull-45 { + left: -45%; + } + + .tablet-grid-50 { + float: left; + width: 50%; + } + + .tablet-prefix-50 { + margin-left: 50%; + } + + .tablet-suffix-50 { + margin-right: 50%; + } + + .tablet-push-50 { + left: 50%; + } + + .tablet-pull-50 { + left: -50%; + } + + .tablet-grid-55 { + float: left; + width: 55%; + } + + .tablet-prefix-55 { + margin-left: 55%; + } + + .tablet-suffix-55 { + margin-right: 55%; + } + + .tablet-push-55 { + left: 55%; + } + + .tablet-pull-55 { + left: -55%; + } + + .tablet-grid-60 { + float: left; + width: 60%; + } + + .tablet-prefix-60 { + margin-left: 60%; + } + + .tablet-suffix-60 { + margin-right: 60%; + } + + .tablet-push-60 { + left: 60%; + } + + .tablet-pull-60 { + left: -60%; + } + + .tablet-grid-65 { + float: left; + width: 65%; + } + + .tablet-prefix-65 { + margin-left: 65%; + } + + .tablet-suffix-65 { + margin-right: 65%; + } + + .tablet-push-65 { + left: 65%; + } + + .tablet-pull-65 { + left: -65%; + } + + .tablet-grid-70 { + float: left; + width: 70%; + } + + .tablet-prefix-70 { + margin-left: 70%; + } + + .tablet-suffix-70 { + margin-right: 70%; + } + + .tablet-push-70 { + left: 70%; + } + + .tablet-pull-70 { + left: -70%; + } + + .tablet-grid-75 { + float: left; + width: 75%; + } + + .tablet-prefix-75 { + margin-left: 75%; + } + + .tablet-suffix-75 { + margin-right: 75%; + } + + .tablet-push-75 { + left: 75%; + } + + .tablet-pull-75 { + left: -75%; + } + + .tablet-grid-80 { + float: left; + width: 80%; + } + + .tablet-prefix-80 { + margin-left: 80%; + } + + .tablet-suffix-80 { + margin-right: 80%; + } + + .tablet-push-80 { + left: 80%; + } + + .tablet-pull-80 { + left: -80%; + } + + .tablet-grid-85 { + float: left; + width: 85%; + } + + .tablet-prefix-85 { + margin-left: 85%; + } + + .tablet-suffix-85 { + margin-right: 85%; + } + + .tablet-push-85 { + left: 85%; + } + + .tablet-pull-85 { + left: -85%; + } + + .tablet-grid-90 { + float: left; + width: 90%; + } + + .tablet-prefix-90 { + margin-left: 90%; + } + + .tablet-suffix-90 { + margin-right: 90%; + } + + .tablet-push-90 { + left: 90%; + } + + .tablet-pull-90 { + left: -90%; + } + + .tablet-grid-95 { + float: left; + width: 95%; + } + + .tablet-prefix-95 { + margin-left: 95%; + } + + .tablet-suffix-95 { + margin-right: 95%; + } + + .tablet-push-95 { + left: 95%; + } + + .tablet-pull-95 { + left: -95%; + } + + .tablet-grid-33 { + float: left; + width: 33.33333%; + } + + .tablet-prefix-33 { + margin-left: 33.33333%; + } + + .tablet-suffix-33 { + margin-right: 33.33333%; + } + + .tablet-push-33 { + left: 33.33333%; + } + + .tablet-pull-33 { + left: -33.33333%; + } + + .tablet-grid-66 { + float: left; + width: 66.66667%; + } + + .tablet-prefix-66 { + margin-left: 66.66667%; + } + + .tablet-suffix-66 { + margin-right: 66.66667%; + } + + .tablet-push-66 { + left: 66.66667%; + } + + .tablet-pull-66 { + left: -66.66667%; + } + + .tablet-grid-100 { + clear: both; + width: 100%; + } +} +@media (min-width: 1220px) { + .push-5, .pull-5, .push-10, .pull-10, .push-15, .pull-15, .push-20, .pull-20, .push-25, .pull-25, .push-30, .pull-30, .push-35, .pull-35, .push-40, .pull-40, .push-45, .pull-45, .push-50, .pull-50, .push-55, .pull-55, .push-60, .pull-60, .push-65, .pull-65, .push-70, .pull-70, .push-75, .pull-75, .push-80, .pull-80, .push-85, .pull-85, .push-90, .pull-90, .push-95, .pull-95, .push-33, .pull-33, .push-66, .pull-66 { + position: relative; + } + + .hide-on-desktop { + display: none !important; + } + + .grid-5 { + float: left; + width: 5%; + } + + .prefix-5 { + margin-left: 5%; + } + + .suffix-5 { + margin-right: 5%; + } + + .push-5 { + left: 5%; + } + + .pull-5 { + left: -5%; + } + + .grid-10 { + float: left; + width: 10%; + } + + .prefix-10 { + margin-left: 10%; + } + + .suffix-10 { + margin-right: 10%; + } + + .push-10 { + left: 10%; + } + + .pull-10 { + left: -10%; + } + + .grid-15 { + float: left; + width: 15%; + } + + .prefix-15 { + margin-left: 15%; + } + + .suffix-15 { + margin-right: 15%; + } + + .push-15 { + left: 15%; + } + + .pull-15 { + left: -15%; + } + + .grid-20 { + float: left; + width: 20%; + } + + .prefix-20 { + margin-left: 20%; + } + + .suffix-20 { + margin-right: 20%; + } + + .push-20 { + left: 20%; + } + + .pull-20 { + left: -20%; + } + + .grid-25 { + float: left; + width: 25%; + } + + .prefix-25 { + margin-left: 25%; + } + + .suffix-25 { + margin-right: 25%; + } + + .push-25 { + left: 25%; + } + + .pull-25 { + left: -25%; + } + + .grid-30 { + float: left; + width: 30%; + } + + .prefix-30 { + margin-left: 30%; + } + + .suffix-30 { + margin-right: 30%; + } + + .push-30 { + left: 30%; + } + + .pull-30 { + left: -30%; + } + + .grid-35 { + float: left; + width: 35%; + } + + .prefix-35 { + margin-left: 35%; + } + + .suffix-35 { + margin-right: 35%; + } + + .push-35 { + left: 35%; + } + + .pull-35 { + left: -35%; + } + + .grid-40 { + float: left; + width: 40%; + } + + .prefix-40 { + margin-left: 40%; + } + + .suffix-40 { + margin-right: 40%; + } + + .push-40 { + left: 40%; + } + + .pull-40 { + left: -40%; + } + + .grid-45 { + float: left; + width: 45%; + } + + .prefix-45 { + margin-left: 45%; + } + + .suffix-45 { + margin-right: 45%; + } + + .push-45 { + left: 45%; + } + + .pull-45 { + left: -45%; + } + + .grid-50 { + float: left; + width: 50%; + } + + .prefix-50 { + margin-left: 50%; + } + + .suffix-50 { + margin-right: 50%; + } + + .push-50 { + left: 50%; + } + + .pull-50 { + left: -50%; + } + + .grid-55 { + float: left; + width: 55%; + } + + .prefix-55 { + margin-left: 55%; + } + + .suffix-55 { + margin-right: 55%; + } + + .push-55 { + left: 55%; + } + + .pull-55 { + left: -55%; + } + + .grid-60 { + float: left; + width: 60%; + } + + .prefix-60 { + margin-left: 60%; + } + + .suffix-60 { + margin-right: 60%; + } + + .push-60 { + left: 60%; + } + + .pull-60 { + left: -60%; + } + + .grid-65 { + float: left; + width: 65%; + } + + .prefix-65 { + margin-left: 65%; + } + + .suffix-65 { + margin-right: 65%; + } + + .push-65 { + left: 65%; + } + + .pull-65 { + left: -65%; + } + + .grid-70 { + float: left; + width: 70%; + } + + .prefix-70 { + margin-left: 70%; + } + + .suffix-70 { + margin-right: 70%; + } + + .push-70 { + left: 70%; + } + + .pull-70 { + left: -70%; + } + + .grid-75 { + float: left; + width: 75%; + } + + .prefix-75 { + margin-left: 75%; + } + + .suffix-75 { + margin-right: 75%; + } + + .push-75 { + left: 75%; + } + + .pull-75 { + left: -75%; + } + + .grid-80 { + float: left; + width: 80%; + } + + .prefix-80 { + margin-left: 80%; + } + + .suffix-80 { + margin-right: 80%; + } + + .push-80 { + left: 80%; + } + + .pull-80 { + left: -80%; + } + + .grid-85 { + float: left; + width: 85%; + } + + .prefix-85 { + margin-left: 85%; + } + + .suffix-85 { + margin-right: 85%; + } + + .push-85 { + left: 85%; + } + + .pull-85 { + left: -85%; + } + + .grid-90 { + float: left; + width: 90%; + } + + .prefix-90 { + margin-left: 90%; + } + + .suffix-90 { + margin-right: 90%; + } + + .push-90 { + left: 90%; + } + + .pull-90 { + left: -90%; + } + + .grid-95 { + float: left; + width: 95%; + } + + .prefix-95 { + margin-left: 95%; + } + + .suffix-95 { + margin-right: 95%; + } + + .push-95 { + left: 95%; + } + + .pull-95 { + left: -95%; + } + + .grid-33 { + float: left; + width: 33.33333%; + } + + .prefix-33 { + margin-left: 33.33333%; + } + + .suffix-33 { + margin-right: 33.33333%; + } + + .push-33 { + left: 33.33333%; + } + + .pull-33 { + left: -33.33333%; + } + + .grid-66 { + float: left; + width: 66.66667%; + } + + .prefix-66 { + margin-left: 66.66667%; + } + + .suffix-66 { + margin-right: 66.66667%; + } + + .push-66 { + left: 66.66667%; + } + + .pull-66 { + left: -66.66667%; + } + .grid-100 { clear: both; width: 100%; From 5f567170a8d6c3c7665b488fc3cba6fa1133222f Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 15 Sep 2026 12:01:26 +0200 Subject: [PATCH 3/5] Load the fonts without the flicker, the way openvidu.io does Render-blocking stylesheet with display=block plus preloads of the faces the first viewport uses, instead of the preload-as-style trick with display=swap that painted the fallback font first. Tomorrow 100, used by nothing, leaves the URL. --- overrides/main.html | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/overrides/main.html b/overrides/main.html index 7aeed88..41b3110 100644 --- a/overrides/main.html +++ b/overrides/main.html @@ -30,17 +30,26 @@ {% block extrahead %} {{ super() }} -{# The site's single font stylesheet (theme.font is false), the same one - openvidu.io loads. Self-hosted at build time by the privacy plugin. #} +{# Fonts, the same block openvidu.io's main.html carries (minus Tomorrow 800, which only its + pricing tables use). `theme.font` is false, so this is the site's only font stylesheet; the + privacy plugin vendors every URL below at build time, preload hrefs included. + No-flicker contract: break any one and text paints twice (fallback, then Tomorrow). + 1. A render-blocking `rel="stylesheet"`, never the preload-as-style + onload trick. + 2. `display=block`, not `swap` (swap paints the fallback first by design). + 3. Preload every face the first viewport needs, or `block` shows invisible text instead: + Tomorrow 300 (Material h1), 400, 500 and 700, Roboto Mono (one latin file serves + 400/500/700), Arciform (header title, same href as extra.css). Latin subset only; + `crossorigin` must match the CSS's CORS fetch or the hint becomes a second download. #} +{# Tomorrow 300 #} +{# Tomorrow 400 #} +{# Tomorrow 500 #} +{# Tomorrow 700 #} +{# Roboto Mono #} + - {% include "partials/og.html" %} {% include "partials/json-ld.html" %} From 247c96741636cfc18f3a02b8536b3db64424b1f8 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 15 Sep 2026 12:02:37 +0200 Subject: [PATCH 4/5] README: the sync check covers Markdown, CSS parity is manual --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cbe9af5..da1b804 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ differences, all listed at the top of the script: When a real difference is meant to stay, add it to the script's rules with a comment saying why — never leave it reported. +**CSS is not compared.** The tutorials' markup relies on classes both sites define: +`docs/stylesheets/unsemantic-grid.css` is the same complete file on both, and `extra.css` here +carries the utilities the synced pages use (`.text-center`, `.w-25`, `.w-50`) plus the selectors +shared with openvidu.io's sheet (footer, product tags, tabbed content, lightbox, newsletter form). +A class openvidu.io adds to a synced page needs its rule here too. + ## Publishing Merging to `main` does not change the live site. From f7e31a2a2636a0496f5725e9039383b4e56427d6 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 15 Sep 2026 17:32:46 +0200 Subject: [PATCH 5/5] Lay out extra.css and colors.css the way openvidu.io does Sections in cascade order (fonts, Material overrides, utilities, components, page areas, responsive), the brand colours as --ov-* tokens in colors.css with the layering note, and the product tag at openvidu.io's single 0.8em size. The rule-set diff against the previous files shows only those token and tag-size substitutions. --- docs/stylesheets/colors.css | 38 ++-- docs/stylesheets/extra.css | 389 ++++++++++++++++++++++-------------- 2 files changed, 264 insertions(+), 163 deletions(-) diff --git a/docs/stylesheets/colors.css b/docs/stylesheets/colors.css index 9380400..262523b 100644 --- a/docs/stylesheets/colors.css +++ b/docs/stylesheets/colors.css @@ -1,11 +1,22 @@ +/* Site palette, laid out like openvidu.io's colors.css: the brand tokens (--ov-*), Material's + colour variables for the site-wide look, then the per-scheme overrides. Every repeated colour + lives here as a token; only white, black and single-use UI colours stay literal elsewhere. */ + :root { - --md-primary-fg-color: #4d4d4d; - --md-primary-fg-color--light: #00c8f7; - --md-primary-fg-color--dark: #0088aa; + --ov-meet-accent-rgb: 6, 211, 98; + --ov-platform-primary: #0088aa; + --ov-platform-primary-rgb: 0, 136, 170; + --ov-platform-accent: #00c8f7; + --ov-nav-grey: #4d4d4d; + --ov-grey-muted: #818181; + + --md-primary-fg-color: var(--ov-nav-grey); + --md-primary-fg-color--light: var(--ov-platform-accent); + --md-primary-fg-color--dark: var(--ov-platform-primary); --md-primary-bg-color: #fff; - --md-primary-bg-color--dark: #0088aa; - --md-accent-fg-color: #0088aa; - --md-accent-fg-color--transparent: #818181; + --md-primary-bg-color--dark: var(--ov-platform-primary); + --md-accent-fg-color: var(--ov-platform-primary); + --md-accent-fg-color--transparent: var(--ov-grey-muted); --md-accent-bg-color: #ffffff; --md-accent-bg-color--light: #ffffff; --md-hue: 190deg; @@ -15,14 +26,16 @@ --slate-md-default-bg-color: hsla(var(--md-hue), 15%, 14%, 1); --slate-md-default-fg-color--light: hsla(var(--md-hue), 15%, 90%, 0.56); } -/* Custom colors for dark mode */ + +/* Dark scheme */ [data-md-color-scheme="slate"] { --md-typeset-a-color: var(--md-primary-fg-color--light); } -/* Custom colors for light mode */ +/* Light scheme */ [data-md-color-scheme="default"] { --md-typeset-a-color: var(--md-primary-fg-color--dark); + hr { background-image: linear-gradient( to right, @@ -32,12 +45,13 @@ transparent 100% ); } + .md-button--primary { background-color: var(--md-accent-fg-color--transparent); border-color: var(--md-accent-fg-color--transparent); -} -img.mediasoup-icon { - filter: brightness(0.5) saturate(2.5); -} + } + img.mediasoup-icon { + filter: brightness(0.5) saturate(2.5); + } } diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 0739eb4..f87a462 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -1,29 +1,32 @@ -.openvidu-tag { - pointer-events: none; - display: inline-block; - margin: 0 3px 0 3px; - color: white; - font-weight: bold; - padding: 0px 5px; - border-radius: 3px; - font-size: 1em; - line-height: 1.8em; - font-family: var(--md-text-font-family); - font-feature-settings: "kern", "liga"; - vertical-align: text-bottom; -} -.openvidu-community-tag { - background-color: rgb(6 211 98 / 80%); -} -.openvidu-pro-tag { - background-color: rgb(0 136 170 / 80%); -} -span:has(> .openvidu-tag) { - display: inline-block; +/* Site-wide stylesheet, loaded on every page after colors.css, laid out like openvidu.io's + extra.css: fonts, Material overrides, utilities, components, page areas, responsive. The + synced tutorials rely on the utilities both sites define (.text-center, .nowrap, .w-25, + .w-50) and on unsemantic-grid.css, which is the same file on both. */ + +/* ========================================================================== + 1. Fonts + ========================================================================== */ + +@font-face { + font-family: "Arciform"; + src: url("/assets/fonts/Arciform.woff2") format("woff2"), + url("/assets/fonts/Arciform.woff") format("woff"); + font-display: swap; } -span:has(> a > .openvidu-tag) { - display: inline-block; + +/* theme.font is false (main.html loads the one Google Fonts stylesheet), so Material's font + variables are declared here instead. */ +:root { + --md-text-font: "Tomorrow"; + --md-code-font: "Roboto Mono"; } + +/* ========================================================================== + 2. Material overrides + ========================================================================== */ + +/* Layout and header */ + .md-grid { max-width: 70rem; } @@ -31,277 +34,361 @@ span:has(> a > .openvidu-tag) { .md-main__inner { margin-bottom: 3.5rem; } + .md-header__topic .md-ellipsis { font-family: Arciform; font-weight: 100; font-size: 18px; } + +/* Typography and content elements */ + .md-typeset .md-button:not(.md-button--primary) { color: var(--md-typeset-color); } + .md-typeset .md-button:hover:not(.md-button--primary) { color: var(--md-accent-bg-color); background-color: var(--md-typeset-color); border-color: var(--md-typeset-color); } + .md-typeset .md-button:focus:not(.md-button--primary) { color: var(--md-accent-bg-color); background-color: var(--md-typeset-color); border-color: var(--md-typeset-color); } + .md-typeset figcaption { max-width: 25rem; font-size: 0.74rem; } + +hr { + border-bottom: none !important; + background-image: linear-gradient( + to right, + transparent 0%, + var(--ov-nav-grey) 25%, + var(--ov-nav-grey) 75%, + transparent 100% + ); + width: 100%; + height: 1px; +} + +/* Content tabs (pymdownx.tabbed) */ + +.tabbed-labels label { + text-align: center; + font-size: 20px; +} + +.tabbed-content { + padding: 0 12px 0 16px; + border: 2px solid var(--md-default-fg-color--lightest); + border-top: none; + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + background-color: var(--md-code-bg-color); +} + +.tabbed-content .tabbed-block code { + background-color: var(--md-default-bg-color); +} + +.tabbed-content .tabbed-block .tabbed-content { + padding: 0; + border: none; + border-radius: 0; +} + +/* Footer (overrides/partials/footer.html) */ + .md-copyright { padding-top: 0.6rem; } + .md-social { padding: 0; margin-left: -0.6rem; } + .md-social__link { height: 2.2rem; width: 2.2rem; line-height: 2.2; } + .md-social__link svg { max-height: 1.1rem; } -.md-footer-meta .md-social { - flex-wrap: wrap; - row-gap: 0.4rem; -} + .footer-grid { width: 100%; text-align: center; padding: 0.8rem 0 1rem 0; } + .grid-container.footer-grid { max-width: none; } -@media (min-width: 1220px) { - .grid-20.footer-products-gap { - margin-left: 1.2rem; - width: calc(20% - 1.2rem); - } -} + .footer-conditions-list { font-size: 0.64rem; display: grid; } + .md-footer-meta .footer-column { text-align: left; } + +.md-footer-meta .md-social { + flex-wrap: wrap; + row-gap: 0.4rem; +} + .md-footer-meta .footer-column h4 { font-weight: 400; font-size: 0.75rem; } + .md-footer-meta .md-copyright { margin-left: 0 !important; padding-top: 0 !important; display: inline-block; vertical-align: top; } + #mc-embedded-subscribe { background-color: inherit; color: var(--slate-md-typeset-color); border-color: var(--slate-md-typeset-color); } + #mc-embedded-subscribe:hover { color: var(--md-accent-bg-color); background-color: hsla(var(--md-hue), 18%, 86%, 0.82); border-color: hsla(var(--md-hue), 18%, 86%, 0.82); } + #mce-EMAIL { padding-left: 10px; background-color: var(--md-footer-fg-color--light); color: black; } + #mce-EMAIL::placeholder { color: rgba(0, 0, 0, 0.75); } -@font-face { - font-family: "Arciform"; - src: url("/assets/fonts/Arciform.woff2") format("woff2"), - url("/assets/fonts/Arciform.woff") format("woff"); - font-display: swap; +/* ========================================================================== + 3. Utilities (the synced tutorials use these; keep them in step with openvidu.io) + ========================================================================== */ + +.nowrap { + white-space: nowrap; +} + +.text-center { + text-align: center; +} + +.w-25 { + width: 25%; +} + +.w-50 { + width: 50%; +} + +/* Screen captures */ +.round-corners { + border-radius: 8px; +} + +/* Icons */ + +.icon { + margin: 5px; +} + +.lg-icon { + font-size: 1.5rem; +} + +.tab-icon { + display: block !important; +} + +/* Marks a link that leaves this site (see CLAUDE.md), as on openvidu.io */ +.external-link-icon { + font-size: 0.75em; +} + +/* A standalone image is centred whether or not the lightbox wrapped it in an anchor + (`skip-gallery` images never get one), and whether its parent is a paragraph or a layout + cell. Same rule as openvidu.io. */ +p:has(> a.glightbox), +p:has(> img), +div[class*="grid-"]:has(> a.glightbox), +div[class*="grid-"]:has(> img) { + text-align: center; +} + +/* ========================================================================== + 4. Components + ========================================================================== */ + +/* COMMUNITY / PRO product tags. One size everywhere: 0.8em of the surrounding text. */ + +.openvidu-tag { + pointer-events: none; + display: inline-block; + margin: 0 3px 0 3px; + color: white; + font-weight: bold; + padding: 0px 5px; + border-radius: 3px; + font-size: 0.8em; + line-height: 1.8em; + font-family: var(--md-text-font-family); + font-feature-settings: "kern", "liga"; + vertical-align: text-bottom; +} + +.openvidu-community-tag { + background-color: rgba(var(--ov-meet-accent-rgb), 0.8); +} + +.openvidu-pro-tag { + background-color: rgba(var(--ov-platform-primary-rgb), 0.8); +} + +span:has(> .openvidu-tag) { + display: inline-block; +} + +span:has(> a > .openvidu-tag) { + display: inline-block; +} + +/* Tutorial index button grids */ + +.tutorials-container { + display: flex; + flex-wrap: wrap; + justify-content: space-evenly; + text-align: center; } +.tutorial-link { + flex: 1; + height: 100px; + width: 162px; + padding: 10px !important; +} + +.no-width { + width: inherit; +} + +/* Lightbox (mkdocs-glightbox) */ + .gslide-image { max-width: 1500px; } + .gslide-image img { background: transparent !important; } + .glightbox-clean .gslide-video { background: transparent !important; } + .glightbox-clean .gslide-video video { background: transparent !important; } -/* GLightbox animations */ .gzoomIn { animation: gzoomIn 0.4s ease !important; } + .gzoomOut { animation: gzoomOut 0.2s ease !important; } + .gfadeOut { animation: gfadeOut 0.2s ease !important; } -/* The about-page feature cards, in the style of openvidu.io's home features: - borderless tiles, a flex header with a big icon beside the name, and three - columns where the width allows. */ + +/* ========================================================================== + 5. Page areas + ========================================================================== */ + +/* About page: feature cards in the style of openvidu.io's home features (borderless tiles, a + flex header with a big icon beside the name, three columns where the width allows) */ + .feature-cards .grid.cards { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); } + .feature-cards .grid.cards > ul > li { border: solid transparent !important; margin: 0.5rem !important; padding: 0.9rem !important; } + .feature-cards .grid.cards > ul > li:hover, .feature-cards .grid.cards > ul > li:focus-within { box-shadow: none !important; } + .feature-cards .grid.cards > ul > li > p:first-child { display: flex; flex-wrap: wrap; align-items: center; row-gap: 0.4em; } + .feature-cards .grid.cards > ul > li .feature-icon { font-size: 3em; flex-shrink: 0; } + .feature-cards .grid.cards > ul > li .feature-name { font-size: 1.25em; margin-left: 12px; font-weight: 600; } -/* The two brand wordmarks in the first card's header: wide glyphs, sized to - read at the height of the names beside them. */ + +/* The two brand wordmarks in the first card's header: wide glyphs, sized to read at the + height of the names beside them. */ .md-typeset .livekit-icon { --md-icon-size: 4.8em; height: auto; flex-shrink: 0; } -/* Mobile extra small */ -@media (max-width: 500px) { - nav { - overflow-x: auto; - } -} - img.mediasoup-icon { max-width: 4.8rem !important; margin-left: 12px; } -/* Content tabs (pymdownx.tabbed) */ -.tabbed-labels label { - text-align: center; - font-size: 20px; -} -.tabbed-content { - padding: 0 12px 0 16px; - border: 2px solid var(--md-default-fg-color--lightest); - border-top: none; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - background-color: var(--md-code-bg-color); -} -.tabbed-content .tabbed-block code { - background-color: var(--md-default-bg-color); -} -.tabbed-content .tabbed-block .tabbed-content { - padding: 0; - border: none; - border-radius: 0; -} -/* Tutorial index button grids */ - -.icon { - margin: 5px; -} -.lg-icon { - font-size: 1.5rem; -} -.tab-icon { - display: block !important; -} -.tutorials-container { - display: flex; - flex-wrap: wrap; - justify-content: space-evenly; - text-align: center; -} -.tutorial-link { - flex: 1; - height: 100px; - width: 162px; - padding: 10px !important; -} -.no-width { - width: inherit; -} - -/* theme.font is false (main.html loads the one Google Fonts stylesheet), so - Material's font variables are declared here instead. */ -:root { - --md-text-font: "Tomorrow"; - --md-code-font: "Roboto Mono"; -} - -/* Marks a link that leaves this site (see CLAUDE.md), as on openvidu.io */ -.external-link-icon { - font-size: 0.75em; -} - -/* Screen captures */ -.round-corners { - border-radius: 8px; -} - -/* A standalone image is centred whether or not the lightbox wrapped it in an - anchor (`skip-gallery` images never get one), and whether its parent is a - paragraph or a layout cell. Same rule as openvidu.io. */ -p:has(> a.glightbox), -p:has(> img), -div[class*="grid-"]:has(> a.glightbox), -div[class*="grid-"]:has(> img) { - text-align: center; -} - -.text-center { - text-align: center; -} - -.w-25 { - width: 25%; -} - -.w-50 { - width: 50%; -} +/* ========================================================================== + 6. Responsive: one block per breakpoint, widest first + ========================================================================== */ -.nowrap { - white-space: nowrap; +@media (min-width: 1220px) { + .grid-20.footer-products-gap { + margin-left: 1.2rem; + width: calc(20% - 1.2rem); + } } -hr { - border-bottom: none !important; - background-image: linear-gradient( - to right, - transparent 0%, - rgba(77, 77, 77, 1) 25%, - rgba(77, 77, 77, 1) 75%, - transparent 100% - ); - width: 100%; - height: 1px; +@media (max-width: 500px) { + nav { + overflow-x: auto; + } }