<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.sojielectronics.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin</id>
	<title>SOJI ELECTRONICS - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.sojielectronics.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin"/>
	<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/wiki/Special:Contributions/Admin"/>
	<updated>2026-05-25T08:33:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1212</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1212"/>
		<updated>2026-05-25T08:32:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: Test video&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;{{YouTube|id=33bgFmoK4y8|width=640|align=center|caption=ABCXYZ}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1211</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1211"/>
		<updated>2026-05-25T08:30:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: Test Video&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=QyeU1MJjEHU|width=640|align=center}}{{YouTube|id=33bgFmoK4y8|width=640|align=center|caption=ABCXYZ}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1210</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1210"/>
		<updated>2026-05-25T08:29:17Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=QyeU1MJjEHU|width=640|align=center}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1209</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1209"/>
		<updated>2026-05-25T08:28:28Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE EMBED via JS&lt;br /&gt;
   Template chỉ output data, JS generate full embed&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function buildEmbed(container) {&lt;br /&gt;
        if (container.dataset.initialized === &#039;1&#039;) return;&lt;br /&gt;
        container.dataset.initialized = &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
        var videoId = container.dataset.videoId;&lt;br /&gt;
        var width = container.dataset.width || &#039;640&#039;;&lt;br /&gt;
        var align = container.dataset.align || &#039;center&#039;;&lt;br /&gt;
        var caption = container.dataset.caption || &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
        if (!videoId) {&lt;br /&gt;
            container.innerHTML = &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Error: missing video ID&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Build container styles&lt;br /&gt;
        container.style.textAlign = align;&lt;br /&gt;
        container.style.margin = &#039;12px 0&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Thumbnail wrapper&lt;br /&gt;
        var thumbWrap = document.createElement(&#039;div&#039;);&lt;br /&gt;
        thumbWrap.className = &#039;soji-yt-thumb-wrap&#039;;&lt;br /&gt;
        thumbWrap.style.cssText = &lt;br /&gt;
            &#039;position: relative;&#039; +&lt;br /&gt;
            &#039;display: inline-block;&#039; +&lt;br /&gt;
            &#039;width: &#039; + width + &#039;px;&#039; +&lt;br /&gt;
            &#039;max-width: 100%;&#039; +&lt;br /&gt;
            &#039;aspect-ratio: 16/9;&#039; +&lt;br /&gt;
            &#039;cursor: pointer;&#039; +&lt;br /&gt;
            &#039;overflow: hidden;&#039; +&lt;br /&gt;
            &#039;border-radius: 8px;&#039; +&lt;br /&gt;
            &#039;background: #000;&#039; +&lt;br /&gt;
            &#039;box-shadow: 0 4px 12px rgba(0,0,0,0.15);&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Thumbnail image&lt;br /&gt;
        var img = document.createElement(&#039;img&#039;);&lt;br /&gt;
        img.src = &#039;https://i.ytimg.com/vi/&#039; + videoId + &#039;/hqdefault.jpg&#039;;&lt;br /&gt;
        img.alt = &#039;Video thumbnail&#039;;&lt;br /&gt;
        img.loading = &#039;lazy&#039;;&lt;br /&gt;
        img.style.cssText = &lt;br /&gt;
            &#039;width: 100%;&#039; +&lt;br /&gt;
            &#039;height: 100%;&#039; +&lt;br /&gt;
            &#039;object-fit: cover;&#039; +&lt;br /&gt;
            &#039;display: block;&#039; +&lt;br /&gt;
            &#039;transition: transform 0.3s, filter 0.2s;&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Try maxresdefault for better quality&lt;br /&gt;
        var hiresTest = new Image();&lt;br /&gt;
        hiresTest.onload = function () {&lt;br /&gt;
            if (hiresTest.naturalWidth &amp;gt; 480) {&lt;br /&gt;
                img.src = &#039;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&#039;;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
        hiresTest.src = &#039;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&#039;;&lt;br /&gt;
&lt;br /&gt;
        // Play button overlay&lt;br /&gt;
        var overlay = document.createElement(&#039;div&#039;);&lt;br /&gt;
        overlay.className = &#039;soji-yt-play-overlay&#039;;&lt;br /&gt;
        overlay.style.cssText = &lt;br /&gt;
            &#039;position: absolute;&#039; +&lt;br /&gt;
            &#039;top: 50%;&#039; +&lt;br /&gt;
            &#039;left: 50%;&#039; +&lt;br /&gt;
            &#039;transform: translate(-50%, -50%);&#039; +&lt;br /&gt;
            &#039;width: 72px;&#039; +&lt;br /&gt;
            &#039;height: 50px;&#039; +&lt;br /&gt;
            &#039;background: rgba(0, 0, 0, 0.7);&#039; +&lt;br /&gt;
            &#039;border-radius: 14px;&#039; +&lt;br /&gt;
            &#039;display: flex;&#039; +&lt;br /&gt;
            &#039;align-items: center;&#039; +&lt;br /&gt;
            &#039;justify-content: center;&#039; +&lt;br /&gt;
            &#039;transition: background 0.2s, transform 0.2s;&#039; +&lt;br /&gt;
            &#039;pointer-events: none;&#039;;&lt;br /&gt;
&lt;br /&gt;
        overlay.innerHTML = &lt;br /&gt;
            &#039;&amp;lt;svg width=&amp;quot;36&amp;quot; height=&amp;quot;26&amp;quot; viewBox=&amp;quot;0 0 36 26&amp;quot; fill=&amp;quot;white&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;polygon points=&amp;quot;14,7 14,19 25,13&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/svg&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        thumbWrap.appendChild(img);&lt;br /&gt;
        thumbWrap.appendChild(overlay);&lt;br /&gt;
&lt;br /&gt;
        // Hover effect&lt;br /&gt;
        thumbWrap.addEventListener(&#039;mouseenter&#039;, function () {&lt;br /&gt;
            overlay.style.background = &#039;#f00&#039;;&lt;br /&gt;
            overlay.style.transform = &#039;translate(-50%, -50%) scale(1.1)&#039;;&lt;br /&gt;
            img.style.filter = &#039;brightness(0.85)&#039;;&lt;br /&gt;
        });&lt;br /&gt;
        thumbWrap.addEventListener(&#039;mouseleave&#039;, function () {&lt;br /&gt;
            overlay.style.background = &#039;rgba(0, 0, 0, 0.7)&#039;;&lt;br /&gt;
            overlay.style.transform = &#039;translate(-50%, -50%) scale(1)&#039;;&lt;br /&gt;
            img.style.filter = &#039;&#039;;&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Click → load iframe&lt;br /&gt;
        thumbWrap.addEventListener(&#039;click&#039;, function () {&lt;br /&gt;
            var iframe = document.createElement(&#039;iframe&#039;);&lt;br /&gt;
            iframe.src = &#039;https://www.youtube-nocookie.com/embed/&#039; + videoId + &lt;br /&gt;
                         &#039;?autoplay=1&amp;amp;rel=0&amp;amp;modestbranding=1&amp;amp;playsinline=1&#039;;&lt;br /&gt;
            iframe.style.cssText = &lt;br /&gt;
                &#039;width: 100%;&#039; +&lt;br /&gt;
                &#039;height: 100%;&#039; +&lt;br /&gt;
                &#039;border: 0;&#039; +&lt;br /&gt;
                &#039;position: absolute;&#039; +&lt;br /&gt;
                &#039;inset: 0;&#039;;&lt;br /&gt;
            iframe.setAttribute(&#039;frameborder&#039;, &#039;0&#039;);&lt;br /&gt;
            iframe.setAttribute(&#039;allow&#039;, &#039;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#039;);&lt;br /&gt;
            iframe.setAttribute(&#039;allowfullscreen&#039;, &#039;true&#039;);&lt;br /&gt;
&lt;br /&gt;
            thumbWrap.innerHTML = &#039;&#039;;&lt;br /&gt;
            thumbWrap.appendChild(iframe);&lt;br /&gt;
            thumbWrap.style.cursor = &#039;default&#039;;&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        container.appendChild(thumbWrap);&lt;br /&gt;
&lt;br /&gt;
        // Caption&lt;br /&gt;
        if (caption) {&lt;br /&gt;
            var captionDiv = document.createElement(&#039;div&#039;);&lt;br /&gt;
            captionDiv.style.cssText = &lt;br /&gt;
                &#039;margin-top: 8px;&#039; +&lt;br /&gt;
                &#039;font-style: italic;&#039; +&lt;br /&gt;
                &#039;color: #666;&#039; +&lt;br /&gt;
                &#039;font-size: 0.9em;&#039;;&lt;br /&gt;
            captionDiv.textContent = caption;&lt;br /&gt;
            container.appendChild(captionDiv);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function initYouTubeEmbeds() {&lt;br /&gt;
        document.querySelectorAll(&#039;.soji-yt-embed&#039;).forEach(buildEmbed);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, initYouTubeEmbeds);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeEmbeds();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:YouTube&amp;diff=1208</id>
		<title>Template:YouTube</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:YouTube&amp;diff=1208"/>
		<updated>2026-05-25T08:27:57Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== YouTube Embed Template ==&lt;br /&gt;
&lt;br /&gt;
Embed YouTube video. Auto-strips query parameters from ID.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Usage:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{YouTube|id=VIDEO_ID|width=640|align=center|caption=Description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{TemplateData&lt;br /&gt;
|description=Embed a YouTube video. Paste video ID (the 11 characters after v= in YouTube URL).&lt;br /&gt;
|params={&lt;br /&gt;
    &amp;quot;id&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;YouTube Video ID&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;required&amp;quot;: true,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Video ID (11 chars). Query parameters auto-stripped.&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;width&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Width (px)&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;number&amp;quot;,&lt;br /&gt;
        &amp;quot;default&amp;quot;: &amp;quot;640&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;align&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Alignment&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;default&amp;quot;: &amp;quot;center&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;left / center / right&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;caption&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Caption&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;required&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;div class=&amp;quot;soji-yt-embed&amp;quot; data-video-id=&amp;quot;{{#explode:{{#explode:{{{id|}}}|?|0}}|&amp;amp;|0}}&amp;quot; data-width=&amp;quot;{{{width|640}}}&amp;quot; data-align=&amp;quot;{{{align|center}}}&amp;quot; data-caption=&amp;quot;{{{caption|}}}&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1207</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1207"/>
		<updated>2026-05-25T08:25:51Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE EMBED - click to play&lt;br /&gt;
   Replace thumbnail with iframe on click&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function initYouTubeEmbeds() {&lt;br /&gt;
        document.querySelectorAll(&#039;.soji-yt-embed&#039;).forEach(function (embed) {&lt;br /&gt;
            if (embed.dataset.initialized === &#039;1&#039;) return;&lt;br /&gt;
            embed.dataset.initialized = &#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
            var thumbWrap = embed.querySelector(&#039;.soji-yt-thumb-wrap&#039;);&lt;br /&gt;
            if (!thumbWrap) return;&lt;br /&gt;
&lt;br /&gt;
            // Hover effect&lt;br /&gt;
            var overlay = embed.querySelector(&#039;.soji-yt-play-overlay&#039;);&lt;br /&gt;
            thumbWrap.addEventListener(&#039;mouseenter&#039;, function () {&lt;br /&gt;
                if (overlay) overlay.style.background = &#039;#f00&#039;;&lt;br /&gt;
            });&lt;br /&gt;
            thumbWrap.addEventListener(&#039;mouseleave&#039;, function () {&lt;br /&gt;
                if (overlay) overlay.style.background = &#039;rgba(0,0,0,0.7)&#039;;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Click → load iframe&lt;br /&gt;
            thumbWrap.addEventListener(&#039;click&#039;, function () {&lt;br /&gt;
                var videoId = embed.dataset.videoId;&lt;br /&gt;
                var width = embed.dataset.width || 640;&lt;br /&gt;
                if (!videoId) return;&lt;br /&gt;
&lt;br /&gt;
                var iframe = document.createElement(&#039;iframe&#039;);&lt;br /&gt;
                iframe.src = &#039;https://www.youtube-nocookie.com/embed/&#039; + videoId + &lt;br /&gt;
                            &#039;?autoplay=1&amp;amp;rel=0&amp;amp;modestbranding=1&amp;amp;playsinline=1&#039;;&lt;br /&gt;
                iframe.style.cssText = &#039;width:100%; height:100%; border:0; position:absolute; inset:0;&#039;;&lt;br /&gt;
                iframe.setAttribute(&#039;frameborder&#039;, &#039;0&#039;);&lt;br /&gt;
                iframe.setAttribute(&#039;allow&#039;, &#039;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&#039;);&lt;br /&gt;
                iframe.setAttribute(&#039;allowfullscreen&#039;, &#039;true&#039;);&lt;br /&gt;
&lt;br /&gt;
                thumbWrap.innerHTML = &#039;&#039;;&lt;br /&gt;
                thumbWrap.appendChild(iframe);&lt;br /&gt;
                thumbWrap.style.cursor = &#039;default&#039;;&lt;br /&gt;
            });&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, initYouTubeEmbeds);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeEmbeds();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:YouTube&amp;diff=1206</id>
		<title>Template:YouTube</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:YouTube&amp;diff=1206"/>
		<updated>2026-05-25T08:25:15Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update Template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
== YouTube Embed Template ==&lt;br /&gt;
&lt;br /&gt;
Embed YouTube video. Auto-strips query parameters from ID.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Usage:&#039;&#039;&#039; &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{YouTube|id=VIDEO_ID|width=640|align=center|caption=Description}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{TemplateData&lt;br /&gt;
|description=Embed a YouTube video. Paste video ID (the 11 characters after v= in YouTube URL).&lt;br /&gt;
|params={&lt;br /&gt;
    &amp;quot;id&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;YouTube Video ID&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;required&amp;quot;: true,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Video ID (11 chars). Query parameters auto-stripped.&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;width&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Width (px)&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;number&amp;quot;,&lt;br /&gt;
        &amp;quot;default&amp;quot;: &amp;quot;640&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;align&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Alignment&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;default&amp;quot;: &amp;quot;center&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;left / center / right&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;caption&amp;quot;: {&lt;br /&gt;
        &amp;quot;label&amp;quot;: &amp;quot;Caption&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;string&amp;quot;,&lt;br /&gt;
        &amp;quot;required&amp;quot;: false&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;div class=&amp;quot;soji-yt-embed&amp;quot; style=&amp;quot;text-align:{{{align|center}}}; margin:12px 0;&amp;quot; data-video-id=&amp;quot;{{#explode:{{#explode:{{{id|}}}|?|0}}|&amp;amp;|0}}&amp;quot; data-width=&amp;quot;{{{width|640}}}&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;soji-yt-thumb-wrap&amp;quot; style=&amp;quot;position:relative; display:inline-block; width:{{{width|640}}}px; max-width:100%; aspect-ratio:16/9; cursor:pointer; overflow:hidden; border-radius:8px; background:#000;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;https://i.ytimg.com/vi/{{#explode:{{#explode:{{{id|}}}|?|0}}|&amp;amp;|0}}/hqdefault.jpg&amp;quot; alt=&amp;quot;Video thumbnail&amp;quot; loading=&amp;quot;lazy&amp;quot; style=&amp;quot;width:100%; height:100%; object-fit:cover; display:block;&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;soji-yt-play-overlay&amp;quot; style=&amp;quot;position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:72px; height:50px; background:rgba(0,0,0,0.7); border-radius:14px; display:flex; align-items:center; justify-content:center; transition:background 0.2s;&amp;quot;&amp;gt;&amp;lt;svg width=&amp;quot;36&amp;quot; height=&amp;quot;26&amp;quot; viewBox=&amp;quot;0 0 36 26&amp;quot; fill=&amp;quot;white&amp;quot;&amp;gt;&amp;lt;polygon points=&amp;quot;14,7 14,19 25,13&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;{{#if:{{{caption|}}}|&amp;lt;div style=&amp;quot;margin-top:8px; font-style:italic; color:#666; font-size:0.9em;&amp;quot;&amp;gt;{{{caption}}}&amp;lt;/div&amp;gt;|}}&amp;lt;/div&amp;gt;&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1205</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1205"/>
		<updated>2026-05-25T08:20:54Z</updated>

		<summary type="html">&lt;p&gt;Admin: Test video&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test 1: Direct iframe HTML ==&lt;br /&gt;
&amp;lt;iframe width=&amp;quot;640&amp;quot; height=&amp;quot;360&amp;quot; &lt;br /&gt;
  src=&amp;quot;https://www.youtube-nocookie.com/embed/QyeU1MJjEHU&amp;quot; &lt;br /&gt;
  frameborder=&amp;quot;0&amp;quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test 2: Template hiện tại ==&lt;br /&gt;
{{YouTube|id=QyeU1MJjEHU|width=640|align=center}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1204</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1204"/>
		<updated>2026-05-25T08:18:22Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1203</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1203"/>
		<updated>2026-05-25T08:05:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE - improved&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function extractVideoId(src) {&lt;br /&gt;
        // Match nhiều format URL&lt;br /&gt;
        var patterns = [&lt;br /&gt;
            /\/embed\/([a-zA-Z0-9_-]{11})/,     // /embed/VIDEOID&lt;br /&gt;
            /[?&amp;amp;]v=([a-zA-Z0-9_-]{11})/,         // ?v=VIDEOID&lt;br /&gt;
            /youtu\.be\/([a-zA-Z0-9_-]{11})/     // youtu.be/VIDEOID&lt;br /&gt;
        ];&lt;br /&gt;
        for (var i = 0; i &amp;lt; patterns.length; i++) {&lt;br /&gt;
            var match = src.match(patterns[i]);&lt;br /&gt;
            if (match) return match[1];&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function initYouTubeFacade() {&lt;br /&gt;
        var iframes = document.querySelectorAll(&lt;br /&gt;
            &#039;iframe[src*=&amp;quot;youtube.com/embed/&amp;quot;], iframe[src*=&amp;quot;youtube-nocookie.com/embed/&amp;quot;]&#039;&lt;br /&gt;
        );&lt;br /&gt;
        iframes.forEach(function (iframe) {&lt;br /&gt;
            var videoId = extractVideoId(iframe.src);&lt;br /&gt;
            if (!videoId) {&lt;br /&gt;
                console.warn(&#039;YouTube facade: cannot extract video ID from&#039;, iframe.src);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var width = iframe.getAttribute(&amp;quot;width&amp;quot;) || iframe.width || 640;&lt;br /&gt;
            var height = iframe.getAttribute(&amp;quot;height&amp;quot;) || iframe.height || 360;&lt;br /&gt;
&lt;br /&gt;
            var facade = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
            facade.className = &amp;quot;soji-yt-facade&amp;quot;;&lt;br /&gt;
            facade.style.maxWidth = width + &amp;quot;px&amp;quot;;&lt;br /&gt;
            facade.setAttribute(&amp;quot;role&amp;quot;, &amp;quot;button&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;tabindex&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            facade.innerHTML =&lt;br /&gt;
                &#039;&amp;lt;img class=&amp;quot;soji-yt-thumb&amp;quot; &#039; +&lt;br /&gt;
                &#039;src=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/hqdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;alt=&amp;quot;Video thumbnail&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button class=&amp;quot;soji-yt-play&amp;quot; aria-label=&amp;quot;Play&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;svg viewBox=&amp;quot;0 0 68 48&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z&amp;quot; fill=&amp;quot;#f00&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M45 24 27 14v20&amp;quot; fill=&amp;quot;#fff&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/svg&amp;gt;&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try maxresdefault if available (higher quality)&lt;br /&gt;
            var img = facade.querySelector(&#039;.soji-yt-thumb&#039;);&lt;br /&gt;
            var hires = new Image();&lt;br /&gt;
            hires.onload = function() {&lt;br /&gt;
                if (hires.naturalWidth &amp;gt; 320) img.src = hires.src;&lt;br /&gt;
            };&lt;br /&gt;
            hires.src = &#039;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&#039;;&lt;br /&gt;
&lt;br /&gt;
            function playVideo() {&lt;br /&gt;
                var realIframe = document.createElement(&amp;quot;iframe&amp;quot;);&lt;br /&gt;
                realIframe.src = &amp;quot;https://www.youtube-nocookie.com/embed/&amp;quot; + videoId + &lt;br /&gt;
                                 &amp;quot;?autoplay=1&amp;amp;rel=0&amp;amp;modestbranding=1&amp;quot;;&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;width&amp;quot;, width);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;height&amp;quot;, height);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;frameborder&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allow&amp;quot;, &amp;quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allowfullscreen&amp;quot;, &amp;quot;true&amp;quot;);&lt;br /&gt;
                realIframe.style.cssText = &amp;quot;width:100%;height:100%;position:absolute;inset:0;border:0;&amp;quot;;&lt;br /&gt;
                facade.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
                facade.appendChild(realIframe);&lt;br /&gt;
                facade.classList.add(&amp;quot;soji-yt-playing&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            facade.addEventListener(&amp;quot;click&amp;quot;, playVideo);&lt;br /&gt;
            facade.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
                if (e.key === &amp;quot;Enter&amp;quot; || e.key === &amp;quot; &amp;quot;) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    playVideo();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            iframe.parentNode.replaceChild(facade, iframe);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, initYouTubeFacade);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeFacade();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1202</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1202"/>
		<updated>2026-05-25T08:03:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation Guide ===&lt;br /&gt;
Step-by-step installation of the sensor on a commercial truck fuel tank, including mounting, wiring, and initial BLE pairing with the SOJI mobile app.&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=33bgFmoK4y8|width=640|align=center|caption=Installation tutorial}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
=== E.g: You can edit title and description as below: ===&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
=== Quick Start Demo ===&lt;br /&gt;
Overview of key features and use cases in under 2 minutes. Best for first-time viewers and decision makers.&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=33bgFmoK4y8|width=640|align=center|caption=Quick start demo}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1201</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1201"/>
		<updated>2026-05-25T07:58:38Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE - improved&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function extractVideoId(src) {&lt;br /&gt;
        // Match nhiều format URL&lt;br /&gt;
        var patterns = [&lt;br /&gt;
            /\/embed\/([a-zA-Z0-9_-]{11})/,     // /embed/VIDEOID&lt;br /&gt;
            /[?&amp;amp;]v=([a-zA-Z0-9_-]{11})/,         // ?v=VIDEOID&lt;br /&gt;
            /youtu\.be\/([a-zA-Z0-9_-]{11})/     // youtu.be/VIDEOID&lt;br /&gt;
        ];&lt;br /&gt;
        for (var i = 0; i &amp;lt; patterns.length; i++) {&lt;br /&gt;
            var match = src.match(patterns[i]);&lt;br /&gt;
            if (match) return match[1];&lt;br /&gt;
        }&lt;br /&gt;
        return null;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function initYouTubeFacade() {&lt;br /&gt;
        var iframes = document.querySelectorAll(&lt;br /&gt;
            &#039;iframe[src*=&amp;quot;youtube.com/embed/&amp;quot;], iframe[src*=&amp;quot;youtube-nocookie.com/embed/&amp;quot;]&#039;&lt;br /&gt;
        );&lt;br /&gt;
        iframes.forEach(function (iframe) {&lt;br /&gt;
            var videoId = extractVideoId(iframe.src);&lt;br /&gt;
            if (!videoId) {&lt;br /&gt;
                console.warn(&#039;YouTube facade: cannot extract video ID from&#039;, iframe.src);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            var width = iframe.getAttribute(&amp;quot;width&amp;quot;) || iframe.width || 640;&lt;br /&gt;
            var height = iframe.getAttribute(&amp;quot;height&amp;quot;) || iframe.height || 360;&lt;br /&gt;
&lt;br /&gt;
            var facade = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
            facade.className = &amp;quot;soji-yt-facade&amp;quot;;&lt;br /&gt;
            facade.style.maxWidth = width + &amp;quot;px&amp;quot;;&lt;br /&gt;
            facade.setAttribute(&amp;quot;role&amp;quot;, &amp;quot;button&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;tabindex&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            facade.innerHTML =&lt;br /&gt;
                &#039;&amp;lt;img class=&amp;quot;soji-yt-thumb&amp;quot; &#039; +&lt;br /&gt;
                &#039;src=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/hqdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;alt=&amp;quot;Video thumbnail&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button class=&amp;quot;soji-yt-play&amp;quot; aria-label=&amp;quot;Play&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;svg viewBox=&amp;quot;0 0 68 48&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z&amp;quot; fill=&amp;quot;#f00&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M45 24 27 14v20&amp;quot; fill=&amp;quot;#fff&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/svg&amp;gt;&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try maxresdefault if available (higher quality)&lt;br /&gt;
            var img = facade.querySelector(&#039;.soji-yt-thumb&#039;);&lt;br /&gt;
            var hires = new Image();&lt;br /&gt;
            hires.onload = function() {&lt;br /&gt;
                if (hires.naturalWidth &amp;gt; 320) img.src = hires.src;&lt;br /&gt;
            };&lt;br /&gt;
            hires.src = &#039;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&#039;;&lt;br /&gt;
&lt;br /&gt;
            function playVideo() {&lt;br /&gt;
                var realIframe = document.createElement(&amp;quot;iframe&amp;quot;);&lt;br /&gt;
                realIframe.src = &amp;quot;https://www.youtube-nocookie.com/embed/&amp;quot; + videoId + &lt;br /&gt;
                                 &amp;quot;?autoplay=1&amp;amp;rel=0&amp;amp;modestbranding=1&amp;quot;;&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;width&amp;quot;, width);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;height&amp;quot;, height);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;frameborder&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allow&amp;quot;, &amp;quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allowfullscreen&amp;quot;, &amp;quot;true&amp;quot;);&lt;br /&gt;
                realIframe.style.cssText = &amp;quot;width:100%;height:100%;position:absolute;inset:0;border:0;&amp;quot;;&lt;br /&gt;
                facade.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
                facade.appendChild(realIframe);&lt;br /&gt;
                facade.classList.add(&amp;quot;soji-yt-playing&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            facade.addEventListener(&amp;quot;click&amp;quot;, playVideo);&lt;br /&gt;
            facade.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
                if (e.key === &amp;quot;Enter&amp;quot; || e.key === &amp;quot; &amp;quot;) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    playVideo();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            iframe.parentNode.replaceChild(facade, iframe);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, initYouTubeFacade);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeFacade();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1200</id>
		<title>LIGO AIR Video</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR_Video&amp;diff=1200"/>
		<updated>2026-05-25T07:56:37Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Videos ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;Installation, demo, and tutorial videos for this product.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;How to add/edit videos:&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Edit existing video&#039;&#039;&#039;: click on the YouTube template box → form opens → change Video ID → Apply&lt;br /&gt;
* &#039;&#039;&#039;Add new video&#039;&#039;&#039;: copy 1 video block (from === title === to {{!}}{{!}}), paste below, edit all 3 fields:&lt;br /&gt;
*# H3 title&lt;br /&gt;
*# Description text&lt;br /&gt;
*# YouTube template (Video ID)&lt;br /&gt;
* &#039;&#039;&#039;Get YouTube Video ID&#039;&#039;&#039;: from URL &amp;lt;code&amp;gt;youtube.com/watch?v=&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;youtu.be/&amp;lt;u&amp;gt;ABC123XYZ&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt; — copy the 11-character ID only (no &amp;lt;code&amp;gt;?si=&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;t=&amp;lt;/code&amp;gt;)&lt;br /&gt;
* &#039;&#039;&#039;How to Insert YouTube video:&#039;&#039;&#039;&lt;br /&gt;
** Press &#039;&#039;&#039;Enter&#039;&#039;&#039; to start a new line&lt;br /&gt;
** Click toolbar &#039;&#039;&#039;Insert&#039;&#039;&#039; (with the down arrow ▼) → &#039;&#039;&#039;Template&#039;&#039;&#039;&lt;br /&gt;
** Search box appears → type &amp;lt;code&amp;gt;YouTube&amp;lt;/code&amp;gt; → select &#039;&#039;&#039;YouTube&#039;&#039;&#039; from dropdown&lt;br /&gt;
** Form opens with fields:&lt;br /&gt;
** &#039;&#039;&#039;YouTube Video ID&#039;&#039;&#039; &#039;&#039;(required)&#039;&#039; — paste the 11-character video ID from YouTube URL&lt;br /&gt;
** &#039;&#039;&#039;Width (px)&#039;&#039;&#039; — default &amp;lt;code&amp;gt;640&amp;lt;/code&amp;gt; (good for most cases). For wider showcase use &amp;lt;code&amp;gt;800&amp;lt;/code&amp;gt;, for compact use &amp;lt;code&amp;gt;480&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Alignment&#039;&#039;&#039; — choose &amp;lt;code&amp;gt;center&amp;lt;/code&amp;gt; (default), &amp;lt;code&amp;gt;left&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;right&amp;lt;/code&amp;gt;&lt;br /&gt;
** &#039;&#039;&#039;Caption&#039;&#039;&#039; &#039;&#039;(optional)&#039;&#039; — short text shown below the video player&lt;br /&gt;
** Click &#039;&#039;&#039;Insert&#039;&#039;&#039; → video preview appears in editor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tips:&#039;&#039;&#039; &lt;br /&gt;
* Upload videos to SOJI YouTube channel first&lt;br /&gt;
* Set videos to &#039;&#039;&#039;Public&#039;&#039;&#039; or &#039;&#039;&#039;Unlisted&#039;&#039;&#039; (NOT Private)&lt;br /&gt;
* In YouTube Studio: enable &#039;&#039;&#039;Allow embedding&#039;&#039;&#039; in Advanced settings&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Installation Guide ===&lt;br /&gt;
Step-by-step installation of the sensor on a commercial truck fuel tank, including mounting, wiring, and initial BLE pairing with the SOJI mobile app.&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=QyeU1MJjEHU|width=640|align=center|caption=Installation tutorial}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;&lt;br /&gt;
=== E.g: You can edit title and description as below: ===&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
=== Quick Start Demo ===&lt;br /&gt;
Overview of key features and use cases in under 2 minutes. Best for first-time viewers and decision makers.&lt;br /&gt;
&lt;br /&gt;
{{YouTube|id=QyeU1MJjEHU|width=640|align=center|caption=Quick start demo}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related Documents ==&lt;br /&gt;
{{RelatedDocuments}}&lt;br /&gt;
&lt;br /&gt;
== Revision History ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;revision-history-auto&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;Loading revision history...&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:LIGO AIR ]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1199</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1199"/>
		<updated>2026-05-25T07:47:07Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE - hiện thumbnail thay vì màn hình đen&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function initYouTubeFacade() {&lt;br /&gt;
        var iframes = document.querySelectorAll(&lt;br /&gt;
            &#039;iframe[src*=&amp;quot;youtube.com/embed/&amp;quot;], iframe[src*=&amp;quot;youtube-nocookie.com/embed/&amp;quot;]&#039;&lt;br /&gt;
        );&lt;br /&gt;
        iframes.forEach(function (iframe) {&lt;br /&gt;
            var match = iframe.src.match(/\/embed\/([^?&amp;amp;\/]+)/);&lt;br /&gt;
            if (!match) return;&lt;br /&gt;
            var videoId = match[1];&lt;br /&gt;
&lt;br /&gt;
            var width = iframe.getAttribute(&amp;quot;width&amp;quot;) || iframe.width || 640;&lt;br /&gt;
            var height = iframe.getAttribute(&amp;quot;height&amp;quot;) || iframe.height || 360;&lt;br /&gt;
            var allow = iframe.getAttribute(&amp;quot;allow&amp;quot;) || &lt;br /&gt;
                        &amp;quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            var facade = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
            facade.className = &amp;quot;soji-yt-facade&amp;quot;;&lt;br /&gt;
            facade.style.maxWidth = width + &amp;quot;px&amp;quot;;&lt;br /&gt;
            facade.dataset.videoId = videoId;&lt;br /&gt;
            facade.dataset.width = width;&lt;br /&gt;
            facade.dataset.height = height;&lt;br /&gt;
            facade.dataset.allow = allow;&lt;br /&gt;
            facade.setAttribute(&amp;quot;role&amp;quot;, &amp;quot;button&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;tabindex&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;aria-label&amp;quot;, &amp;quot;Play video&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            facade.innerHTML =&lt;br /&gt;
                &#039;&amp;lt;img class=&amp;quot;soji-yt-thumb&amp;quot; &#039; +&lt;br /&gt;
                &#039;src=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/hqdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;data-hires=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;alt=&amp;quot;Video thumbnail&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button class=&amp;quot;soji-yt-play&amp;quot; aria-label=&amp;quot;Play&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;svg viewBox=&amp;quot;0 0 68 48&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z&amp;quot; class=&amp;quot;soji-yt-play-bg&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M45 24 27 14v20&amp;quot; fill=&amp;quot;#fff&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/svg&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            /* Try loading hi-res thumbnail; fall back to hqdefault if fail */&lt;br /&gt;
            var thumb = facade.querySelector(&amp;quot;.soji-yt-thumb&amp;quot;);&lt;br /&gt;
            var hires = thumb.dataset.hires;&lt;br /&gt;
            var test = new Image();&lt;br /&gt;
            test.onload = function () {&lt;br /&gt;
                if (test.width &amp;gt; 320) thumb.src = hires;&lt;br /&gt;
            };&lt;br /&gt;
            test.src = hires;&lt;br /&gt;
&lt;br /&gt;
            function playVideo() {&lt;br /&gt;
                var realIframe = document.createElement(&amp;quot;iframe&amp;quot;);&lt;br /&gt;
                realIframe.src = &amp;quot;https://www.youtube.com/embed/&amp;quot; + videoId + &amp;quot;?autoplay=1&amp;amp;rel=0&amp;quot;;&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;width&amp;quot;, width);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;height&amp;quot;, height);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;frameborder&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allow&amp;quot;, allow);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allowfullscreen&amp;quot;, &amp;quot;true&amp;quot;);&lt;br /&gt;
                facade.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
                facade.appendChild(realIframe);&lt;br /&gt;
                facade.classList.add(&amp;quot;soji-yt-playing&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            facade.addEventListener(&amp;quot;click&amp;quot;, playVideo);&lt;br /&gt;
            facade.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
                if (e.key === &amp;quot;Enter&amp;quot; || e.key === &amp;quot; &amp;quot;) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    playVideo();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            iframe.parentNode.replaceChild(facade, iframe);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, initYouTubeFacade);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeFacade();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Floating Buttons: move to body level&lt;br /&gt;
 *  Escape mw-body-content stacking context&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
(function () {&lt;br /&gt;
    function moveFloatingButtonsToBody() {&lt;br /&gt;
        var fb = document.getElementById(&#039;floating-buttons&#039;);&lt;br /&gt;
        if (!fb) return;&lt;br /&gt;
        &lt;br /&gt;
        // Already at body level → skip&lt;br /&gt;
        if (fb.parentElement === document.body) return;&lt;br /&gt;
        &lt;br /&gt;
        document.body.appendChild(fb);&lt;br /&gt;
        &lt;br /&gt;
        // Force styles&lt;br /&gt;
        fb.style.position = &#039;fixed&#039;;&lt;br /&gt;
        fb.style.zIndex = &#039;99999&#039;;&lt;br /&gt;
        fb.style.bottom = &#039;24px&#039;;&lt;br /&gt;
        fb.style.right = &#039;24px&#039;;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (document.readyState === &#039;loading&#039;) {&lt;br /&gt;
        document.addEventListener(&#039;DOMContentLoaded&#039;, moveFloatingButtonsToBody);&lt;br /&gt;
    } else {&lt;br /&gt;
        moveFloatingButtonsToBody();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Re-check sau 1s để chắc chắn (nếu floating-buttons được tạo bằng JS khác sau)&lt;br /&gt;
    setTimeout(moveFloatingButtonsToBody, 1000);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1198</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1198"/>
		<updated>2026-05-25T07:43:46Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link,&lt;br /&gt;
.soji-footer-link:visited,&lt;br /&gt;
.soji-footer-link:link,&lt;br /&gt;
.soji-footer-link:active {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 320px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Bỏ hover effect trên card (không border, không shadow, không transform) */&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pass clicks through icon và description xuống stretched link */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-desc,&lt;br /&gt;
.main-page-product-no-icon {&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link giữ pointer-events bình thường */&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    pointer-events: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chỉ highlight title khi hover card (giống 4 category cards bottom) */&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FLOATING BUTTONS - luôn trên top&lt;br /&gt;
   ========================= */&lt;br /&gt;
#floating-buttons {&lt;br /&gt;
    position: fixed !important;&lt;br /&gt;
    z-index: 99999 !important;&lt;br /&gt;
    /* Position: thường là góc dưới phải */&lt;br /&gt;
    bottom: 24px;&lt;br /&gt;
    right: 24px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#floating-buttons button,&lt;br /&gt;
#floating-buttons a {&lt;br /&gt;
    z-index: 99999 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo footer KHÔNG che các button này */&lt;br /&gt;
.soji-site-footer,&lt;br /&gt;
#footer,&lt;br /&gt;
.mw-footer-container {&lt;br /&gt;
    z-index: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1197</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1197"/>
		<updated>2026-05-25T07:40:54Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update btn&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link,&lt;br /&gt;
.soji-footer-link:visited,&lt;br /&gt;
.soji-footer-link:link,&lt;br /&gt;
.soji-footer-link:active {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 320px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Bỏ hover effect trên card (không border, không shadow, không transform) */&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pass clicks through icon và description xuống stretched link */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-desc,&lt;br /&gt;
.main-page-product-no-icon {&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link giữ pointer-events bình thường */&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    pointer-events: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chỉ highlight title khi hover card (giống 4 category cards bottom) */&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FLOATING BUTTONS - luôn trên footer&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Target tất cả floating button thường gặp */&lt;br /&gt;
.mw-back-to-top,&lt;br /&gt;
.vector-back-to-top,&lt;br /&gt;
button[class*=&amp;quot;back-to-top&amp;quot;],&lt;br /&gt;
button[class*=&amp;quot;scroll-to-top&amp;quot;],&lt;br /&gt;
.scroll-to-top,&lt;br /&gt;
.vector-toc-btn,&lt;br /&gt;
.cdx-button[aria-label*=&amp;quot;top&amp;quot; i],&lt;br /&gt;
.cdx-button[aria-label*=&amp;quot;Back&amp;quot; i],&lt;br /&gt;
[class*=&amp;quot;floating-button&amp;quot;],&lt;br /&gt;
[class*=&amp;quot;fab-button&amp;quot;] {&lt;br /&gt;
    z-index: 99999 !important;&lt;br /&gt;
    position: fixed !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo footer SOJI không che button */&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    z-index: 1 !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nếu có sticky-header conflict */&lt;br /&gt;
.vector-sticky-header {&lt;br /&gt;
    z-index: 1000 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=File:Icon-accessories.svg&amp;diff=1196</id>
		<title>File:Icon-accessories.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=File:Icon-accessories.svg&amp;diff=1196"/>
		<updated>2026-05-25T07:35:59Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=File:Icon-faq.svg&amp;diff=1195</id>
		<title>File:Icon-faq.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=File:Icon-faq.svg&amp;diff=1195"/>
		<updated>2026-05-25T07:35:50Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=File:Icon-info.svg&amp;diff=1194</id>
		<title>File:Icon-info.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=File:Icon-info.svg&amp;diff=1194"/>
		<updated>2026-05-25T07:35:40Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=File:Icon-software.svg&amp;diff=1193</id>
		<title>File:Icon-software.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=File:Icon-software.svg&amp;diff=1193"/>
		<updated>2026-05-25T07:35:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1192</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.js&amp;diff=1192"/>
		<updated>2026-05-22T06:41:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;(function () {&lt;br /&gt;
    function esc(text) {&lt;br /&gt;
        return String(text || &amp;quot;&amp;quot;).replace(/[&amp;amp;&amp;lt;&amp;gt;&amp;quot;]/g, function (m) {&lt;br /&gt;
            return { &amp;quot;&amp;amp;&amp;quot;: &amp;quot;&amp;amp;amp;&amp;quot;, &amp;quot;&amp;lt;&amp;quot;: &amp;quot;&amp;amp;lt;&amp;quot;, &amp;quot;&amp;gt;&amp;quot;: &amp;quot;&amp;amp;gt;&amp;quot;, &#039;&amp;quot;&#039;: &amp;quot;&amp;amp;quot;&amp;quot; }[m];&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    var ICONS = {&lt;br /&gt;
        location: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 010-5 2.5 2.5 0 010 5z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        phone: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M12 1a9 9 0 00-9 9v7a3 3 0 003 3h3v-8H5v-2a7 7 0 0114 0v2h-4v8h3a3 3 0 003-3v-7a9 9 0 00-9-9z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        email: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;4&amp;quot;/&amp;gt;&amp;lt;path d=&amp;quot;M16 8v5a3 3 0 006 0v-1a10 10 0 10-4 8&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        clock: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; stroke-linejoin=&amp;quot;round&amp;quot;&amp;gt;&amp;lt;circle cx=&amp;quot;12&amp;quot; cy=&amp;quot;12&amp;quot; r=&amp;quot;10&amp;quot;/&amp;gt;&amp;lt;polyline points=&amp;quot;12 6 12 12 16 14&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        facebook: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M22 12a10 10 0 10-11.56 9.88v-6.99H7.9V12h2.54V9.8c0-2.51 1.49-3.89 3.77-3.89 1.09 0 2.24.2 2.24.2v2.46h-1.26c-1.24 0-1.63.77-1.63 1.56V12h2.77l-.44 2.89h-2.33v6.99A10 10 0 0022 12z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        whatsapp: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M17.5 14.4c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.7.9-.9 1.1-.2.2-.3.2-.6.1-.3-.1-1.2-.4-2.3-1.4-.9-.8-1.4-1.7-1.6-2-.2-.3 0-.5.1-.6.1-.1.3-.3.4-.5.1-.2.2-.3.3-.5.1-.2 0-.4 0-.5 0-.1-.7-1.7-1-2.3-.3-.6-.5-.5-.7-.5h-.6c-.2 0-.5.1-.8.4-.3.3-1 1-1 2.5s1.1 2.9 1.2 3.1c.1.2 2.1 3.2 5.1 4.5.7.3 1.3.5 1.7.6.7.2 1.4.2 1.9.1.6-.1 1.7-.7 2-1.4.2-.7.2-1.3.2-1.4-.1-.1-.3-.2-.5-.3zM12 2a10 10 0 00-8.5 15.3L2 22l4.8-1.4A10 10 0 1012 2z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        linkedin: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2zM8.3 18.3H5.7V9.7h2.6v8.6zM7 8.5a1.5 1.5 0 110-3 1.5 1.5 0 010 3zm11.3 9.8h-2.6v-4.2c0-1 0-2.3-1.4-2.3s-1.6 1.1-1.6 2.2v4.3h-2.6V9.7h2.5v1.2a2.7 2.7 0 012.5-1.4c2.6 0 3.1 1.7 3.1 4v4.8z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;,&lt;br /&gt;
        youtube: &#039;&amp;lt;svg viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;currentColor&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M23.5 6.2a3 3 0 00-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 00.5 6.2 31.3 31.3 0 000 12a31.3 31.3 0 00.5 5.8 3 3 0 002.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 002.1-2.1A31.3 31.3 0 0024 12a31.3 31.3 0 00-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;&#039;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    function getIcon(name) {&lt;br /&gt;
        return &#039;&amp;lt;span class=&amp;quot;soji-footer-icon&amp;quot;&amp;gt;&#039; + (ICONS[name] || &amp;quot;&amp;quot;) + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function renderLink(item, extraClass) {&lt;br /&gt;
    var cls = extraClass ? &#039; class=&amp;quot;&#039; + extraClass + &#039;&amp;quot;&#039; : &amp;quot;&amp;quot;;&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    return &#039;&amp;lt;a&#039; + cls + &#039; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot;&amp;gt;&#039; + esc(item.label) + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    function buildCompany(company) {&lt;br /&gt;
        if (!company) return &amp;quot;&amp;quot;;&lt;br /&gt;
        var contacts = (company.contacts || []).map(function (c) {&lt;br /&gt;
            return &#039;&amp;lt;li class=&amp;quot;soji-footer-contact&amp;quot;&amp;gt;&#039; + getIcon(c.icon) +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;&#039; + esc(c.text) + &amp;quot;&amp;lt;/span&amp;gt;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-company&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;h2 class=&amp;quot;soji-footer-company-name&amp;quot;&amp;gt;&#039; + esc(company.name) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;ul class=&amp;quot;soji-footer-contact-list&amp;quot;&amp;gt;&#039; + contacts + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildColumns(columns) {&lt;br /&gt;
        return (columns || []).map(function (col) {&lt;br /&gt;
            var items = (col.items || []).map(function (item) {&lt;br /&gt;
                return &amp;quot;&amp;lt;li&amp;gt;&amp;quot; + renderLink(item, &amp;quot;soji-footer-link&amp;quot;) + &amp;quot;&amp;lt;/li&amp;gt;&amp;quot;;&lt;br /&gt;
            }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
            return [&lt;br /&gt;
                &#039;&amp;lt;section class=&amp;quot;soji-footer-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
                &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(col.title) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;ul&amp;gt;&amp;quot; + items + &amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;,&lt;br /&gt;
                &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
            ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
        }).join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildSubscribe(data) {&lt;br /&gt;
        var sub = data.subscribe || {};&lt;br /&gt;
        var social = (data.social || []).map(function (item) {&lt;br /&gt;
    var href = item.href ? esc(item.href) : &amp;quot;#&amp;quot;;&lt;br /&gt;
    var icon = item.icon&lt;br /&gt;
        ? getIcon(item.icon)&lt;br /&gt;
        : esc(item.short || item.label.charAt(0));&lt;br /&gt;
    return &#039;&amp;lt;a class=&amp;quot;soji-footer-social-item&amp;quot; href=&amp;quot;&#039; + href + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; aria-label=&amp;quot;&#039; + esc(item.label) + &#039;&amp;quot;&amp;gt;&#039; + icon + &amp;quot;&amp;lt;/a&amp;gt;&amp;quot;;&lt;br /&gt;
}).join(&amp;quot;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section class=&amp;quot;soji-footer-subscribe-col&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &amp;quot;&amp;lt;h2&amp;gt;&amp;quot; + esc(sub.title || &amp;quot;Subscribe&amp;quot;) + &amp;quot;&amp;lt;/h2&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;form class=&amp;quot;soji-footer-subscribe-form&amp;quot; action=&amp;quot;&#039; + esc(sub.action || &amp;quot;#&amp;quot;) + &#039;&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;input type=&amp;quot;email&amp;quot; name=&amp;quot;email&amp;quot; class=&amp;quot;soji-footer-subscribe-input&amp;quot; placeholder=&amp;quot;&#039; + esc(sub.placeholder || &amp;quot;Email Address *&amp;quot;) + &#039;&amp;quot; required&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;button type=&amp;quot;submit&amp;quot; class=&amp;quot;soji-footer-subscribe-btn&amp;quot;&amp;gt;&#039; + esc(sub.buttonLabel || &amp;quot;Send&amp;quot;) + &amp;quot;&amp;lt;/button&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/form&amp;gt;&amp;quot;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-social&amp;quot;&amp;gt;&#039; + social + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function buildFooter(data) {&lt;br /&gt;
        return [&lt;br /&gt;
            &#039;&amp;lt;section id=&amp;quot;soji-site-footer&amp;quot; class=&amp;quot;soji-site-footer&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-shell&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;soji-footer-grid&amp;quot;&amp;gt;&#039;,&lt;br /&gt;
            buildCompany(data.company),&lt;br /&gt;
            buildColumns(data.columns),&lt;br /&gt;
            buildSubscribe(data),&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            data.copyright ? &#039;&amp;lt;div class=&amp;quot;soji-footer-copy&amp;quot;&amp;gt;&#039; + esc(data.copyright) + &amp;quot;&amp;lt;/div&amp;gt;&amp;quot; : &amp;quot;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;,&lt;br /&gt;
            &amp;quot;&amp;lt;/section&amp;gt;&amp;quot;&lt;br /&gt;
        ].join(&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
function injectFooter(data) {&lt;br /&gt;
    if (document.getElementById(&amp;quot;soji-site-footer&amp;quot;)) return;&lt;br /&gt;
    document.body.insertAdjacentHTML(&amp;quot;beforeend&amp;quot;, buildFooter(data));&lt;br /&gt;
    document.body.classList.add(&amp;quot;has-soji-footer&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    function init() {&lt;br /&gt;
        fetch(&amp;quot;/index.php?title=MediaWiki:FooterData.json&amp;amp;action=raw&amp;quot;)&lt;br /&gt;
            .then(function (r) { return r.text(); })&lt;br /&gt;
            .then(function (text) { return JSON.parse(text); })&lt;br /&gt;
            .then(injectFooter)&lt;br /&gt;
            .catch(function (err) { console.error(&amp;quot;Footer load failed:&amp;quot;, err); });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, init);&lt;br /&gt;
    } else {&lt;br /&gt;
        init();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    if (mw.config.get(&#039;wgNamespaceNumber&#039;) &amp;lt; 0) return;&lt;br /&gt;
&lt;br /&gt;
    var title = mw.config.get(&#039;wgTitle&#039;);&lt;br /&gt;
    var pageName = mw.config.get(&#039;wgPageName&#039;).replace(/_/g, &#039; &#039;);&lt;br /&gt;
&lt;br /&gt;
    // Page Main Page: không cần breadcrumb&lt;br /&gt;
    if (pageName === &#039;Main Page&#039;) return;&lt;br /&gt;
&lt;br /&gt;
    // Lấy category trực tiếp của page hoặc của category page hiện tại&lt;br /&gt;
    var initialCats = mw.config.get(&#039;wgCategories&#039;) || [];&lt;br /&gt;
    if (!initialCats.length) return;&lt;br /&gt;
&lt;br /&gt;
    var api = new mw.Api();&lt;br /&gt;
    var chain = [];&lt;br /&gt;
    var seen = {};&lt;br /&gt;
&lt;br /&gt;
    // Đi ngược lên cây qua API&lt;br /&gt;
    function walkUp(catName) {&lt;br /&gt;
        if (!catName || seen[catName] || catName === &#039;Main Page&#039;) {&lt;br /&gt;
            return $.Deferred().resolve();&lt;br /&gt;
        }&lt;br /&gt;
        seen[catName] = true;&lt;br /&gt;
        chain.unshift(catName);&lt;br /&gt;
&lt;br /&gt;
        return api.get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            titles: &#039;Category:&#039; + catName,&lt;br /&gt;
            prop: &#039;categories&#039;,&lt;br /&gt;
            cllimit: 1,&lt;br /&gt;
            format: &#039;json&#039;,&lt;br /&gt;
            formatversion: 2&lt;br /&gt;
        }).then(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.pages) || [];&lt;br /&gt;
            if (!pages.length || !pages[0].categories) return;&lt;br /&gt;
            var parent = pages[0].categories[0].title.replace(/^Category:/, &#039;&#039;);&lt;br /&gt;
            return walkUp(parent);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    walkUp(initialCats[0]).then(function () {&lt;br /&gt;
        var parts = [&lt;br /&gt;
            &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Main Page&#039;) + &#039;&amp;quot;&amp;gt;Main Page&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
        ];&lt;br /&gt;
        chain.forEach(function (c) {&lt;br /&gt;
            parts.push(&#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(c) + &#039;&amp;quot;&amp;gt;&#039; + c + &#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
        });&lt;br /&gt;
        parts.push(&#039;&amp;lt;strong&amp;gt;&#039; + title + &#039;&amp;lt;/strong&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
        var html = &#039;&amp;lt;nav class=&amp;quot;custom-breadcrumb&amp;quot;&amp;gt;&#039; + parts.join(&#039; &amp;amp;gt; &#039;) + &#039;&amp;lt;/nav&amp;gt;&#039;;&lt;br /&gt;
        $(&#039;#mw-content-text&#039;).before(html);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Tự động thêm target=&amp;quot;_blank&amp;quot; cho mọi link tới file .pdf&lt;br /&gt;
    $(&#039;a[href$=&amp;quot;.pdf&amp;quot;], a[href*=&amp;quot;.pdf?&amp;quot;], a[href*=&amp;quot;/file/&amp;quot;][href*=&amp;quot;.pdf&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        $(this).attr(&#039;target&#039;, &#039;_blank&#039;);&lt;br /&gt;
        $(this).attr(&#039;rel&#039;, &#039;noopener noreferrer&#039;);&lt;br /&gt;
        // Thêm icon PDF nhỏ&lt;br /&gt;
        if (!$(this).find(&#039;.pdf-icon&#039;).length) {&lt;br /&gt;
            $(this).append(&#039; &amp;lt;span class=&amp;quot;pdf-icon&amp;quot; title=&amp;quot;Open PDF in new tab&amp;quot;&amp;gt;📄&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Force &amp;quot;View&amp;quot; links to open in new tab&lt;br /&gt;
    $(&#039;.doc-view a&#039;).attr({&lt;br /&gt;
        target: &#039;_blank&#039;,&lt;br /&gt;
        rel: &#039;noopener noreferrer&#039;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    // Force &amp;quot;Download&amp;quot; links to trigger file download&lt;br /&gt;
    $(&#039;.doc-download a&#039;).each(function () {&lt;br /&gt;
        var $a = $(this);&lt;br /&gt;
        var href = $a.attr(&#039;href&#039;);&lt;br /&gt;
        // Extract filename from URL&lt;br /&gt;
        var match = href.match(/\/([^\/]+\.(?:pdf|zip|doc|docx|xls|xlsx))$/i);&lt;br /&gt;
        if (match) {&lt;br /&gt;
            $a.attr(&#039;download&#039;, match[1]);&lt;br /&gt;
        } else {&lt;br /&gt;
            $a.attr(&#039;download&#039;, &#039;&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Auto-collapse TOC sub-headings on page load&lt;br /&gt;
 * Only show H2 (main Heading) by default&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    var attempts = 0;&lt;br /&gt;
    var maxAttempts = 15;&lt;br /&gt;
&lt;br /&gt;
    function collapseAllTOC() {&lt;br /&gt;
        // Find all expanded toggle buttons in TOC&lt;br /&gt;
        var $toggles = $(&#039;.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;]&#039;);&lt;br /&gt;
        &lt;br /&gt;
        if ($toggles.length &amp;gt; 0) {&lt;br /&gt;
            $toggles.each(function () {&lt;br /&gt;
                // Click toggle to collapse (triggers Vue.js handler)&lt;br /&gt;
                this.click();&lt;br /&gt;
            });&lt;br /&gt;
        } else if (attempts &amp;lt; maxAttempts) {&lt;br /&gt;
            // TOC chưa render xong, retry&lt;br /&gt;
            attempts++;&lt;br /&gt;
            setTimeout(collapseAllTOC, 100);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    collapseAllTOC();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Sync chevron arrow with collapsible state&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    $(&#039;.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]&#039;).each(function () {&lt;br /&gt;
        var $toggle = $(this);&lt;br /&gt;
        var match = $toggle.attr(&#039;class&#039;).match(/mw-customtoggle-(\S+)/);&lt;br /&gt;
        if (!match) return;&lt;br /&gt;
&lt;br /&gt;
        var $target = $(&#039;#mw-customcollapsible-&#039; + match[1]);&lt;br /&gt;
        if (!$target.length) return;&lt;br /&gt;
&lt;br /&gt;
        function syncArrow() {&lt;br /&gt;
            if ($target.hasClass(&#039;mw-collapsed&#039;)) {&lt;br /&gt;
                $toggle.removeClass(&#039;is-expanded&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $toggle.addClass(&#039;is-expanded&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Initial state&lt;br /&gt;
        syncArrow();&lt;br /&gt;
&lt;br /&gt;
        // Update on click&lt;br /&gt;
        $toggle.on(&#039;click&#039;, function () {&lt;br /&gt;
            setTimeout(syncArrow, 50);&lt;br /&gt;
        });&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================&lt;br /&gt;
 * Pending Changes Badge for Reviewers&lt;br /&gt;
 * Show notification of pending changes count&lt;br /&gt;
 * ============================================ */&lt;br /&gt;
$(function () {&lt;br /&gt;
    // Chỉ show cho user có quyền review (reviewer, sysop, admin)&lt;br /&gt;
    var userGroups = mw.config.get(&#039;wgUserGroups&#039;) || [];&lt;br /&gt;
    var hasReviewRights = userGroups.some(function (g) {&lt;br /&gt;
        return [&#039;reviewer&#039;, &#039;sysop&#039;, &#039;bureaucrat&#039;].indexOf(g) !== -1;&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    if (!hasReviewRights) {&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Fetch pending count from API&lt;br /&gt;
    function fetchPendingCount() {&lt;br /&gt;
        new mw.Api().get({&lt;br /&gt;
            action: &#039;query&#039;,&lt;br /&gt;
            list: &#039;oldreviewedpages&#039;,&lt;br /&gt;
            ornamespace: &#039;0|14&#039;,&lt;br /&gt;
            orfilterredir: &#039;nonredirects&#039;,&lt;br /&gt;
            orlimit: 500,&lt;br /&gt;
            format: &#039;json&#039;&lt;br /&gt;
        }).done(function (data) {&lt;br /&gt;
            var pages = (data.query &amp;amp;&amp;amp; data.query.oldreviewedpages) || [];&lt;br /&gt;
            updateBadge(pages.length);&lt;br /&gt;
        }).fail(function (err) {&lt;br /&gt;
            console.log(&#039;Failed to fetch pending changes:&#039;, err);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Update or create badge in sidebar&lt;br /&gt;
    function updateBadge(count) {&lt;br /&gt;
        var $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
&lt;br /&gt;
        if (!$badge.length) {&lt;br /&gt;
            // Tạo badge mới — tìm sidebar và prepend&lt;br /&gt;
            var badgeHtml =&lt;br /&gt;
                &#039;&amp;lt;div id=&amp;quot;pending-reviews-badge&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;padding: 12px 16px;&#039; +&lt;br /&gt;
                &#039;margin: 12px 8px;&#039; +&lt;br /&gt;
                &#039;background: #fff3e0;&#039; +&lt;br /&gt;
                &#039;border: 1px solid #f57c00;&#039; +&lt;br /&gt;
                &#039;border-left: 4px solid #e65100;&#039; +&lt;br /&gt;
                &#039;border-radius: 4px;&#039; +&lt;br /&gt;
                &#039;cursor: pointer;&#039; +&lt;br /&gt;
                &#039;transition: background 0.2s;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;&#039; + mw.util.getUrl(&#039;Special:PendingChanges&#039;) + &#039;&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;color: #e65100;&#039; +&lt;br /&gt;
                &#039;text-decoration: none;&#039; +&lt;br /&gt;
                &#039;font-weight: 600;&#039; +&lt;br /&gt;
                &#039;font-size: 0.95em;&#039; +&lt;br /&gt;
                &#039;display: block;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;⚠️ &amp;lt;span id=&amp;quot;pending-count&amp;quot; style=&amp;quot;&#039; +&lt;br /&gt;
                &#039;display: inline-block;&#039; +&lt;br /&gt;
                &#039;background: #e65100;&#039; +&lt;br /&gt;
                &#039;color: white;&#039; +&lt;br /&gt;
                &#039;padding: 2px 10px;&#039; +&lt;br /&gt;
                &#039;border-radius: 12px;&#039; +&lt;br /&gt;
                &#039;margin: 0 6px;&#039; +&lt;br /&gt;
                &#039;font-weight: 700;&#039; +&lt;br /&gt;
                &#039;&amp;quot;&amp;gt;0&amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;pending review&#039; +&lt;br /&gt;
                &#039;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            // Try multiple sidebar selectors (Vector 2022 + legacy)&lt;br /&gt;
            var $sidebar = $(&#039;#mw-panel .vector-main-menu-content&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel-toc-list&#039;)&lt;br /&gt;
                .add(&#039;#mw-panel&#039;)&lt;br /&gt;
                .add(&#039;.vector-main-menu&#039;)&lt;br /&gt;
                .first();&lt;br /&gt;
&lt;br /&gt;
            if ($sidebar.length) {&lt;br /&gt;
                $sidebar.prepend(badgeHtml);&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                // Fallback: insert at top of body&lt;br /&gt;
                $(&#039;body&#039;).prepend(&lt;br /&gt;
                    &#039;&amp;lt;div style=&amp;quot;position:fixed;top:60px;right:20px;z-index:9999;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    badgeHtml + &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
                $badge = $(&#039;#pending-reviews-badge&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $(&#039;#pending-count&#039;).text(count);&lt;br /&gt;
&lt;br /&gt;
        if (count === 0) {&lt;br /&gt;
            $badge.hide();&lt;br /&gt;
        } else {&lt;br /&gt;
            $badge.show();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Initial fetch&lt;br /&gt;
    fetchPendingCount();&lt;br /&gt;
&lt;br /&gt;
    // Refresh every 60 seconds&lt;br /&gt;
    setInterval(fetchPendingCount, 60000);&lt;br /&gt;
&lt;br /&gt;
    // Also refresh on focus (when user comes back to tab)&lt;br /&gt;
    $(window).on(&#039;focus&#039;, fetchPendingCount);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder auto-hide&lt;br /&gt;
 *  Logic: section nào có user content → ẩn placeholder trong section đó&lt;br /&gt;
 *         section trống chỉ có placeholder → vẫn hiển thị (làm hint)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function hidePlaceholdersInFilledSections() {&lt;br /&gt;
        var $headings = $( &#039;.mw-parser-output h1, .mw-parser-output h2&#039; );&lt;br /&gt;
        if ( !$headings.length ) return;&lt;br /&gt;
&lt;br /&gt;
        $headings.each( function ( i ) {&lt;br /&gt;
            var $h = $( this );&lt;br /&gt;
            var $nextH = $headings.eq( i + 1 );&lt;br /&gt;
            var $sectionEls = $nextH.length ? $h.nextUntil( $nextH ) : $h.nextAll();&lt;br /&gt;
&lt;br /&gt;
            // Đọc text trong section, loại trừ text của placeholder&lt;br /&gt;
            var contentText = &#039;&#039;;&lt;br /&gt;
            $sectionEls.each( function () {&lt;br /&gt;
                var $clone = $( this ).clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                contentText += $clone.text();&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Nếu section có user content (ngoài placeholder) → ẩn placeholder&lt;br /&gt;
            if ( contentText.trim().length &amp;gt; 0 ) {&lt;br /&gt;
                $sectionEls.find( &#039;.soji-placeholder&#039; ).hide();&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // Xử lý riêng placeholder trong table cell:&lt;br /&gt;
        // Nếu cell có content khác → ẩn placeholder của cell đó&lt;br /&gt;
        $( &#039;.soji-placeholder:visible&#039; ).each( function () {&lt;br /&gt;
            var $ph = $( this );&lt;br /&gt;
            var $cell = $ph.closest( &#039;td, th&#039; );&lt;br /&gt;
            if ( $cell.length ) {&lt;br /&gt;
                var $clone = $cell.clone();&lt;br /&gt;
                $clone.find( &#039;.soji-placeholder&#039; ).remove();&lt;br /&gt;
                if ( $clone.text().trim().length &amp;gt; 0 ) {&lt;br /&gt;
                    $ph.hide();&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( hidePlaceholdersInFilledSections );&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit summary helper&lt;br /&gt;
 *  Show hint placeholder in edit summary field&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; &amp;amp;&amp;amp; mw.config.get( &#039;wgAction&#039; ) !== &#039;submit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        var $summary = $( &#039;#wpSummary&#039; );&lt;br /&gt;
        if ( !$summary.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Add placeholder hint&lt;br /&gt;
        $summary.attr( &#039;placeholder&#039;,&lt;br /&gt;
            &#039;Describe your changes (will appear in Revision History — e.g., &amp;quot;Updated electrical specs&amp;quot;, &amp;quot;Fixed typo in safety section&amp;quot;)&#039;&lt;br /&gt;
        );&lt;br /&gt;
&lt;br /&gt;
        // Add character counter&lt;br /&gt;
        var $counter = $( &#039;&amp;lt;div class=&amp;quot;fw-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; color:#666; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; );&lt;br /&gt;
        $summary.after( $counter );&lt;br /&gt;
&lt;br /&gt;
        function updateCounter() {&lt;br /&gt;
            var len = $summary.val().length;&lt;br /&gt;
            var color = len &amp;lt; 10 ? &#039;#d33&#039; : len &amp;lt; 30 ? &#039;#f80&#039; : &#039;#0a0&#039;;&lt;br /&gt;
            $counter.html(&lt;br /&gt;
                &#039;&amp;lt;span style=&amp;quot;color:&#039; + color + &#039;&amp;quot;&amp;gt;&#039; + len + &#039;&amp;lt;/span&amp;gt; characters &#039; +&lt;br /&gt;
                ( len &amp;lt; 10 ? &#039;(too short — describe what changed)&#039; :&lt;br /&gt;
                  len &amp;lt; 30 ? &#039;(acceptable — be more specific)&#039; :&lt;br /&gt;
                  &#039;(good — descriptive)&#039; )&lt;br /&gt;
            );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        $summary.on( &#039;input keyup&#039;, updateCounter );&lt;br /&gt;
        updateCounter();&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto Revision History Table&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function formatVersion( n ) {&lt;br /&gt;
        var major = Math.floor( ( n - 1 ) / 10 ) + 1;&lt;br /&gt;
        var minor = ( n - 1 ) % 10;&lt;br /&gt;
        return major + &#039;.&#039; + minor;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatDate( isoTimestamp ) {&lt;br /&gt;
        var d = new Date( isoTimestamp );&lt;br /&gt;
        var dd = ( &#039;0&#039; + d.getDate() ).slice( -2 );&lt;br /&gt;
        var mm = ( &#039;0&#039; + ( d.getMonth() + 1 ) ).slice( -2 );&lt;br /&gt;
        return dd + &#039;/&#039; + mm + &#039;/&#039; + d.getFullYear();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function escapeHtml( str ) {&lt;br /&gt;
        return ( str || &#039;&#039; )&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&amp;amp;amp;&#039; )&lt;br /&gt;
            .replace( /&amp;lt;/g, &#039;&amp;amp;lt;&#039; )&lt;br /&gt;
            .replace( /&amp;gt;/g, &#039;&amp;amp;gt;&#039; )&lt;br /&gt;
            .replace( /&amp;quot;/g, &#039;&amp;amp;quot;&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function renderRevisionHistory() {&lt;br /&gt;
    var $containers = $( &#039;.revision-history-auto&#039; );&lt;br /&gt;
    if ( !$containers.length ) return;&lt;br /&gt;
&lt;br /&gt;
    var pageName = mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
&lt;br /&gt;
    new mw.Api().get( {&lt;br /&gt;
        action: &#039;query&#039;,&lt;br /&gt;
        prop: &#039;revisions&#039;,&lt;br /&gt;
        titles: pageName,&lt;br /&gt;
        rvprop: &#039;timestamp|user|comment&#039;,&lt;br /&gt;
        rvlimit: &#039;max&#039;,&lt;br /&gt;
        rvdir: &#039;newer&#039;,           // oldest first&lt;br /&gt;
        formatversion: 2&lt;br /&gt;
    } ).done( function ( data ) {&lt;br /&gt;
        var page = data.query.pages[ 0 ];&lt;br /&gt;
        if ( !page || !page.revisions ) {&lt;br /&gt;
            $containers.html( &#039;&amp;lt;em&amp;gt;No revision history available.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var revisions = page.revisions;&lt;br /&gt;
&lt;br /&gt;
        // Case 1: chỉ có 1 revision = template gen, chưa edit&lt;br /&gt;
        if ( revisions.length &amp;lt; 2 ) {&lt;br /&gt;
            $containers.html(&lt;br /&gt;
                &#039;&amp;lt;em style=&amp;quot;color:#888&amp;quot;&amp;gt;No edits yet. &#039; +&lt;br /&gt;
                &#039;Edit this page to update the content — the first edit will be recorded as v1.0.&amp;lt;/em&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Case 2: có &amp;gt;= 2 revisions&lt;br /&gt;
        // - revision 0 = template creation → SKIP&lt;br /&gt;
        // - revision 1 = first edit → v1.0&lt;br /&gt;
        // - revision 2 = second edit → v1.1&lt;br /&gt;
        // - ...&lt;br /&gt;
        var rows = [];&lt;br /&gt;
&lt;br /&gt;
        revisions.forEach( function ( rev, i ) {&lt;br /&gt;
            // Skip first revision (template creation)&lt;br /&gt;
            if ( i === 0 ) return;&lt;br /&gt;
&lt;br /&gt;
            // i=1 → v1.0, i=2 → v1.1, ...&lt;br /&gt;
            var version = formatVersion( i );&lt;br /&gt;
            var date    = formatDate( rev.timestamp );&lt;br /&gt;
            var author  = escapeHtml( rev.user || &#039;unknown&#039; );&lt;br /&gt;
            var desc    = escapeHtml( rev.comment ) || &#039;&amp;lt;em&amp;gt;(no edit summary)&amp;lt;/em&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            rows.push(&lt;br /&gt;
                &#039;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&#039; + date + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&amp;lt;strong&amp;gt;v&#039; + version + &#039;&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + author + &#039;&amp;lt;/td&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;td&amp;gt;&#039; + desc + &#039;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Newest first&lt;br /&gt;
        rows.reverse();&lt;br /&gt;
&lt;br /&gt;
        var html =&lt;br /&gt;
            &#039;&amp;lt;table class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:15%&amp;quot;&amp;gt;Date&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:10%&amp;quot;&amp;gt;Version&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th style=&amp;quot;width:20%&amp;quot;&amp;gt;Author&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;tbody&amp;gt;&#039; + rows.join( &#039;&#039; ) + &#039;&amp;lt;/tbody&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/table&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
        $containers.html( html );&lt;br /&gt;
    } ).fail( function ( err ) {&lt;br /&gt;
        $containers.html( &#039;&amp;lt;em style=&amp;quot;color:#d33&amp;quot;&amp;gt;Failed to load revision history.&amp;lt;/em&amp;gt;&#039; );&lt;br /&gt;
    } );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
    $( renderRevisionHistory );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Force edit summary in VisualEditor save dialog&lt;br /&gt;
 *  Disable Save button until summary is non-empty (min 5 chars)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var MIN_LENGTH = 5;&lt;br /&gt;
&lt;br /&gt;
    function setupVEEnforcement() {&lt;br /&gt;
        // Wait for VE save dialog to appear&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            var $dialog = $( &#039;.ve-ui-mwSaveDialog:visible&#039; );&lt;br /&gt;
            if ( !$dialog.length ) return;&lt;br /&gt;
            if ( $dialog.data( &#039;summary-enforced&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            $dialog.data( &#039;summary-enforced&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            var $summaryInput = $dialog.find( &#039;textarea[name=&amp;quot;wpSummary&amp;quot;], input[name=&amp;quot;wpSummary&amp;quot;]&#039; );&lt;br /&gt;
            if ( !$summaryInput.length ) {&lt;br /&gt;
                $summaryInput = $dialog.find( &#039;.ve-ui-mwSaveDialog-summary textarea, .ve-ui-mwSaveDialog-summary input&#039; );&lt;br /&gt;
            }&lt;br /&gt;
            if ( !$summaryInput.length ) return;&lt;br /&gt;
&lt;br /&gt;
            var $saveBtn = $dialog.find( &#039;.oo-ui-flaggedElement-primary button, button.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            if ( !$saveBtn.length ) {&lt;br /&gt;
                $saveBtn = $dialog.find( &#039;a.oo-ui-flaggedElement-primary&#039; );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add hint message above summary&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-hint&#039; ).length ) {&lt;br /&gt;
                $summaryInput.before(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-hint&amp;quot; style=&amp;quot;background:#fff3cd; color:#856404; padding:8px 12px; border-left:4px solid #ffc107; margin-bottom:8px; font-size:0.9em; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;⚠ &amp;lt;strong&amp;gt;Edit summary required.&amp;lt;/strong&amp;gt; Describe what you changed (minimum &#039; + MIN_LENGTH + &#039; characters). Used for Revision History.&#039; +&lt;br /&gt;
                    &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Add counter&lt;br /&gt;
            if ( !$dialog.find( &#039;.soji-summary-counter&#039; ).length ) {&lt;br /&gt;
                $summaryInput.after(&lt;br /&gt;
                    &#039;&amp;lt;div class=&amp;quot;soji-summary-counter&amp;quot; style=&amp;quot;font-size:0.85em; margin-top:4px;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
                );&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            function updateState() {&lt;br /&gt;
                var len = $summaryInput.val().trim().length;&lt;br /&gt;
                var $counter = $dialog.find( &#039;.soji-summary-counter&#039; );&lt;br /&gt;
&lt;br /&gt;
                if ( len === 0 ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#d33&amp;quot;&amp;gt;⚠ Empty — please describe your changes&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else if ( len &amp;lt; MIN_LENGTH ) {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#f80&amp;quot;&amp;gt;⚠ Too short (&#039; + len + &#039;/&#039; + MIN_LENGTH + &#039; chars minimum)&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    disableSaveButton( $saveBtn );&lt;br /&gt;
                } else {&lt;br /&gt;
                    $counter.html( &#039;&amp;lt;span style=&amp;quot;color:#0a0&amp;quot;&amp;gt;✓ &#039; + len + &#039; characters — good&amp;lt;/span&amp;gt;&#039; );&lt;br /&gt;
                    enableSaveButton( $saveBtn );&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            $summaryInput.on( &#039;input keyup change&#039;, updateState );&lt;br /&gt;
            updateState();&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function disableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;0.5&#039; ).css( &#039;pointer-events&#039;, &#039;none&#039; );&lt;br /&gt;
        $btn.attr( &#039;aria-disabled&#039;, &#039;true&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function enableSaveButton( $btn ) {&lt;br /&gt;
        $btn.css( &#039;opacity&#039;, &#039;&#039; ).css( &#039;pointer-events&#039;, &#039;&#039; );&lt;br /&gt;
        $btn.removeAttr( &#039;aria-disabled&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( setupVEEnforcement );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Edit Draft Auto-Save (localStorage)&lt;br /&gt;
 *  Save draft mỗi 30s, restore khi mở lại edit&lt;br /&gt;
 *  Backup cho trường hợp stash expire hoặc browser crash&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var SAVE_INTERVAL = 30 * 1000;  // 30 seconds&lt;br /&gt;
    var DRAFT_TTL    = 30 * 24 * 60 * 60 * 1000;  // 30 days&lt;br /&gt;
    var STORAGE_PREFIX = &#039;mw-draft-&#039;;&lt;br /&gt;
&lt;br /&gt;
    function getDraftKey() {&lt;br /&gt;
        return STORAGE_PREFIX + mw.config.get( &#039;wgPageName&#039; );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function saveDraft( content ) {&lt;br /&gt;
        try {&lt;br /&gt;
            var data = {&lt;br /&gt;
                content: content,&lt;br /&gt;
                timestamp: Date.now(),&lt;br /&gt;
                page: mw.config.get( &#039;wgPageName&#039; ),&lt;br /&gt;
                user: mw.config.get( &#039;wgUserName&#039; )&lt;br /&gt;
            };&lt;br /&gt;
            localStorage.setItem( getDraftKey(), JSON.stringify( data ) );&lt;br /&gt;
            return true;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            console.warn( &#039;Failed to save draft:&#039;, e );&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function loadDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            var raw = localStorage.getItem( getDraftKey() );&lt;br /&gt;
            if ( !raw ) return null;&lt;br /&gt;
            var data = JSON.parse( raw );&lt;br /&gt;
            if ( Date.now() - data.timestamp &amp;gt; DRAFT_TTL ) {&lt;br /&gt;
                localStorage.removeItem( getDraftKey() );&lt;br /&gt;
                return null;&lt;br /&gt;
            }&lt;br /&gt;
            return data;&lt;br /&gt;
        } catch ( e ) {&lt;br /&gt;
            return null;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function clearDraft() {&lt;br /&gt;
        try {&lt;br /&gt;
            localStorage.removeItem( getDraftKey() );&lt;br /&gt;
        } catch ( e ) {}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatAge( ts ) {&lt;br /&gt;
        var diff = Date.now() - ts;&lt;br /&gt;
        var mins = Math.floor( diff / 60000 );&lt;br /&gt;
        if ( mins &amp;lt; 1 ) return &#039;just now&#039;;&lt;br /&gt;
        if ( mins &amp;lt; 60 ) return mins + &#039; min ago&#039;;&lt;br /&gt;
        var hrs = Math.floor( mins / 60 );&lt;br /&gt;
        if ( hrs &amp;lt; 24 ) return hrs + &#039; hour&#039; + ( hrs &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
        var days = Math.floor( hrs / 24 );&lt;br /&gt;
        return days + &#039; day&#039; + ( days &amp;gt; 1 ? &#039;s&#039; : &#039;&#039; ) + &#039; ago&#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupSourceEditor() {&lt;br /&gt;
        var $textarea = $( &#039;#wpTextbox1&#039; );&lt;br /&gt;
        if ( !$textarea.length ) return;&lt;br /&gt;
&lt;br /&gt;
        // Restore draft on load&lt;br /&gt;
        var draft = loadDraft();&lt;br /&gt;
        if ( draft &amp;amp;&amp;amp; draft.content !== $textarea.val() ) {&lt;br /&gt;
            var age = formatAge( draft.timestamp );&lt;br /&gt;
            var $banner = $(&lt;br /&gt;
                &#039;&amp;lt;div class=&amp;quot;mw-draft-banner&amp;quot; style=&amp;quot;background:#fff3cd; border-left:4px solid #ffc107; padding:10px 14px; margin:8px 0; border-radius:3px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;📝 Unsaved draft found&amp;lt;/strong&amp;gt; (&#039; + age + &#039;)&amp;lt;br&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-restore&amp;quot; style=&amp;quot;margin-top:6px; margin-right:8px;&amp;quot;&amp;gt;Restore draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;mw-draft-discard&amp;quot; style=&amp;quot;margin-top:6px;&amp;quot;&amp;gt;Discard draft&amp;lt;/button&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
            );&lt;br /&gt;
            $textarea.before( $banner );&lt;br /&gt;
&lt;br /&gt;
            $banner.find( &#039;.mw-draft-restore&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                $textarea.val( draft.content );&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
            $banner.find( &#039;.mw-draft-discard&#039; ).on( &#039;click&#039;, function () {&lt;br /&gt;
                clearDraft();&lt;br /&gt;
                $banner.remove();&lt;br /&gt;
            } );&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Auto-save every 30s&lt;br /&gt;
        var saveTimer = setInterval( function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
            showSaveIndicator();&lt;br /&gt;
        }, SAVE_INTERVAL );&lt;br /&gt;
&lt;br /&gt;
        // Save on every change (throttled)&lt;br /&gt;
        var changeTimer;&lt;br /&gt;
        $textarea.on( &#039;input&#039;, function () {&lt;br /&gt;
            clearTimeout( changeTimer );&lt;br /&gt;
            changeTimer = setTimeout( function () {&lt;br /&gt;
                saveDraft( $textarea.val() );&lt;br /&gt;
            }, 2000 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Clear draft on successful save&lt;br /&gt;
        $( &#039;#editform&#039; ).on( &#039;submit&#039;, function () {&lt;br /&gt;
            // Wait a bit, then clear if save successful (page redirected)&lt;br /&gt;
            setTimeout( clearDraft, 500 );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        // Save on tab close&lt;br /&gt;
        window.addEventListener( &#039;beforeunload&#039;, function () {&lt;br /&gt;
            saveDraft( $textarea.val() );&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function setupVisualEditor() {&lt;br /&gt;
        // VE saves to its own state, but we can backup the wikitext periodically&lt;br /&gt;
        mw.hook( &#039;ve.activationComplete&#039; ).add( function () {&lt;br /&gt;
            var saveTimer = setInterval( function () {&lt;br /&gt;
                if ( !mw.libs.ve || !mw.libs.ve.targetLoader ) return;&lt;br /&gt;
                try {&lt;br /&gt;
                    var target = ve.init.target;&lt;br /&gt;
                    if ( target &amp;amp;&amp;amp; target.getSurface ) {&lt;br /&gt;
                        var surface = target.getSurface();&lt;br /&gt;
                        if ( surface ) {&lt;br /&gt;
                            var html = surface.getHtml();&lt;br /&gt;
                            saveDraft( html );&lt;br /&gt;
                            showSaveIndicator();&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch ( e ) {}&lt;br /&gt;
            }, SAVE_INTERVAL );&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.deactivationComplete&#039; ).add( function () {&lt;br /&gt;
            // Don&#039;t clear automatically — user may want to reopen&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        mw.hook( &#039;ve.saveComplete&#039; ).add( function () {&lt;br /&gt;
            clearDraft();&lt;br /&gt;
        } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function showSaveIndicator() {&lt;br /&gt;
        var $existing = $( &#039;#mw-draft-indicator&#039; );&lt;br /&gt;
        if ( $existing.length ) {&lt;br /&gt;
            $existing.show().delay( 2000 ).fadeOut( 500 );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;div id=&amp;quot;mw-draft-indicator&amp;quot; style=&amp;quot;position:fixed; bottom:20px; right:20px; background:#0a0; color:white; padding:6px 12px; border-radius:4px; font-size:0.85em; z-index:9999; box-shadow:0 2px 8px rgba(0,0,0,0.2);&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;💾 Draft saved locally&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $( &#039;body&#039; ).append( $indicator );&lt;br /&gt;
        $indicator.delay( 2000 ).fadeOut( 500, function () { $( this ).remove(); } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        var action = mw.config.get( &#039;wgAction&#039; );&lt;br /&gt;
        if ( action === &#039;edit&#039; || action === &#039;submit&#039; ) {&lt;br /&gt;
            setupSourceEditor();&lt;br /&gt;
        }&lt;br /&gt;
        if ( mw.config.get( &#039;wgVisualEditor&#039; ) ) {&lt;br /&gt;
            setupVisualEditor();&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  MultiBoilerplate auto-load on dropdown change&lt;br /&gt;
 *  Use URL navigation instead of form submission (more reliable)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $, mw ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    $( function () {&lt;br /&gt;
        // Only run on edit action&lt;br /&gt;
        if ( mw.config.get( &#039;wgAction&#039; ) !== &#039;edit&#039; ) return;&lt;br /&gt;
&lt;br /&gt;
        // Find MultiBoilerplate dropdown — try multiple selectors&lt;br /&gt;
        var $select = $( &#039;select[name=&amp;quot;boilerplate&amp;quot;], #multiboilerplate-select, #boilerplate-select&#039; );&lt;br /&gt;
&lt;br /&gt;
        if ( !$select.length ) {&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] No boilerplate dropdown found on this page&#039; );&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        console.log( &#039;[MB-AutoLoad] Found dropdown:&#039;, $select[ 0 ] );&lt;br /&gt;
&lt;br /&gt;
        // Find Load button to hide it&lt;br /&gt;
        var $form = $select.closest( &#039;form&#039; );&lt;br /&gt;
        var $submitBtn = $form.find( &#039;input[type=&amp;quot;submit&amp;quot;], button[type=&amp;quot;submit&amp;quot;]&#039; ).filter( function () {&lt;br /&gt;
            var text = ( $( this ).val() || $( this ).text() || &#039;&#039; ).toLowerCase();&lt;br /&gt;
            return text.indexOf( &#039;load&#039; ) !== -1 || text.indexOf( &#039;boilerplate&#039; ) !== -1;&lt;br /&gt;
        } );&lt;br /&gt;
&lt;br /&gt;
        $submitBtn.hide();&lt;br /&gt;
&lt;br /&gt;
        // Add loading indicator&lt;br /&gt;
        var $indicator = $(&lt;br /&gt;
            &#039;&amp;lt;span class=&amp;quot;mb-loading-indicator&amp;quot; style=&amp;quot;margin-left:8px; color:#0054A6; font-style:italic; display:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;⏳ Loading template...&#039; +&lt;br /&gt;
            &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        );&lt;br /&gt;
        $select.after( $indicator );&lt;br /&gt;
&lt;br /&gt;
        // Auto-load on dropdown change&lt;br /&gt;
        $select.on( &#039;change&#039;, function () {&lt;br /&gt;
            var value = $( this ).val();&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Selected:&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            if ( !value || value === &#039;&#039; || value === &#039;-&#039; ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Show loading&lt;br /&gt;
            $indicator.show();&lt;br /&gt;
            $select.prop( &#039;disabled&#039;, true );&lt;br /&gt;
&lt;br /&gt;
            // Build URL with boilerplate parameter&lt;br /&gt;
            var url = new URL( window.location.href );&lt;br /&gt;
            url.searchParams.set( &#039;boilerplate&#039;, value );&lt;br /&gt;
&lt;br /&gt;
            console.log( &#039;[MB-AutoLoad] Navigating to:&#039;, url.toString() );&lt;br /&gt;
&lt;br /&gt;
            // Small delay for visual feedback&lt;br /&gt;
            setTimeout( function () {&lt;br /&gt;
                window.location.href = url.toString();&lt;br /&gt;
            }, 300 );&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
} )( jQuery, mediaWiki );&lt;br /&gt;
/* Auto-convert spaces to dashes in software-card filename hints */&lt;br /&gt;
$(function() {&lt;br /&gt;
    $(&#039;.software-card-no-icon-text code&#039;).each(function() {&lt;br /&gt;
        var text = $(this).text();&lt;br /&gt;
        // Replace spaces with dashes&lt;br /&gt;
        $(this).text(text.replace(/ /g, &#039;-&#039;));&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Filename hint formatter&lt;br /&gt;
 *  Convert spaces → dashes, strip special chars&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function cleanFilename( text ) {&lt;br /&gt;
        return text&lt;br /&gt;
            .replace( /&amp;amp;amp;/g, &#039;&amp;amp;&#039; )      // decode HTML entity first&lt;br /&gt;
            .replace( /&amp;amp;#38;/g, &#039;&amp;amp;&#039; )&lt;br /&gt;
            .replace( / &amp;amp; /g, &#039;-&#039; )         // &amp;quot; &amp;amp; &amp;quot; → &amp;quot;-&amp;quot;&lt;br /&gt;
            .replace( /&amp;amp;/g, &#039;&#039; )            // remove remaining &amp;amp;&lt;br /&gt;
            .replace( / /g, &#039;-&#039; )           // space → dash&lt;br /&gt;
            .replace( /-+/g, &#039;-&#039; );         // multiple dashes → single&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function formatFilenameHints() {&lt;br /&gt;
        var selectors = [&lt;br /&gt;
            &#039;.cert-card-missing code&#039;,&lt;br /&gt;
            &#039;.software-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.accessory-card-no-icon-text code&#039;,&lt;br /&gt;
            &#039;.product-no-image-text code&#039;,&lt;br /&gt;
            &#039;.faq-card-no-icon-text code&#039;&lt;br /&gt;
        ].join( &#039;, &#039; );&lt;br /&gt;
&lt;br /&gt;
        $( selectors ).each( function () {&lt;br /&gt;
            var $code = $( this );&lt;br /&gt;
            if ( $code.data( &#039;filename-formatted&#039; ) ) return;&lt;br /&gt;
&lt;br /&gt;
            var text = $code.text();&lt;br /&gt;
            var formatted = cleanFilename( text );&lt;br /&gt;
&lt;br /&gt;
            if ( formatted !== text ) {&lt;br /&gt;
                $code.text( formatted );&lt;br /&gt;
            }&lt;br /&gt;
            $code.data( &#039;filename-formatted&#039;, &#039;1&#039; );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $( formatFilenameHints );&lt;br /&gt;
&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var observer = new MutationObserver( function () {&lt;br /&gt;
            formatFilenameHints();&lt;br /&gt;
        });&lt;br /&gt;
        observer.observe( document.body, { childList: true, subtree: true } );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* Real-time filter for dynamically loaded sidebar items */&lt;br /&gt;
( function ( $ ) {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    var BLOCKED_PATTERNS = [&lt;br /&gt;
        &#039;Product_Change_Notifications&#039;,&lt;br /&gt;
        &#039;Product Change Notifications&#039;,&lt;br /&gt;
        &#039;Firmware_Changelog&#039;,&lt;br /&gt;
        &#039;Firmware Changelog&#039;,&lt;br /&gt;
        &#039;Promotional_Material&#039;,&lt;br /&gt;
        &#039;Promotional Material&#039;,&lt;br /&gt;
        &#039;Certifications&#039;,&lt;br /&gt;
        &#039;Certification_%26_Approvals&#039;,&lt;br /&gt;
        &#039;Certification &amp;amp; Approvals&#039;&lt;br /&gt;
    ];&lt;br /&gt;
&lt;br /&gt;
    function hideBlocked( context ) {&lt;br /&gt;
        var $context = context ? $( context ) : $( document );&lt;br /&gt;
        $context.find( &#039;#p-categorytree-portlet a, #mw-panel a&#039; ).each( function () {&lt;br /&gt;
            var $link = $( this );&lt;br /&gt;
            var href = $link.attr( &#039;href&#039; ) || &#039;&#039;;&lt;br /&gt;
            var text = $link.text();&lt;br /&gt;
&lt;br /&gt;
            for ( var i = 0; i &amp;lt; BLOCKED_PATTERNS.length; i++ ) {&lt;br /&gt;
                var pattern = BLOCKED_PATTERNS[ i ];&lt;br /&gt;
                if ( href.indexOf( pattern ) !== -1 || text.indexOf( pattern.replace( /_/g, &#039; &#039; ) ) !== -1 ) {&lt;br /&gt;
                    $link.closest( &#039;li, .CategoryTreeItem&#039; ).addClass( &#039;sidebar-hidden&#039; );&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Run immediately&lt;br /&gt;
    hideBlocked();&lt;br /&gt;
&lt;br /&gt;
    // Observe sidebar for dynamic content&lt;br /&gt;
    if ( window.MutationObserver ) {&lt;br /&gt;
        var sidebar = document.querySelector( &#039;#p-categorytree-portlet, #mw-panel&#039; );&lt;br /&gt;
        if ( sidebar ) {&lt;br /&gt;
            new MutationObserver( function ( mutations ) {&lt;br /&gt;
                mutations.forEach( function ( m ) {&lt;br /&gt;
                    if ( m.addedNodes.length &amp;gt; 0 ) {&lt;br /&gt;
                        hideBlocked( m.target );&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
            }).observe( sidebar, {&lt;br /&gt;
                childList: true,&lt;br /&gt;
                subtree: true&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
})( jQuery );&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Auto-play video on scroll into view (IntersectionObserver)&lt;br /&gt;
 *  Play when visible, pause when scrolled out, loop infinitely&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
( function () {&lt;br /&gt;
    &#039;use strict&#039;;&lt;br /&gt;
&lt;br /&gt;
    function setupScrollVideos() {&lt;br /&gt;
        if ( !( &#039;IntersectionObserver&#039; in window ) ) return;&lt;br /&gt;
&lt;br /&gt;
        var videos = document.querySelectorAll( &#039;video.scroll-play, .scroll-play video&#039; );&lt;br /&gt;
        if ( !videos.length ) return;&lt;br /&gt;
&lt;br /&gt;
        var observer = new IntersectionObserver( function ( entries ) {&lt;br /&gt;
            entries.forEach( function ( entry ) {&lt;br /&gt;
                var video = entry.target;&lt;br /&gt;
                if ( entry.isIntersecting ) {&lt;br /&gt;
                    video.play().catch( function () {&lt;br /&gt;
                        // Autoplay blocked by browser, mute and try again&lt;br /&gt;
                        video.muted = true;&lt;br /&gt;
                        video.play();&lt;br /&gt;
                    });&lt;br /&gt;
                } else {&lt;br /&gt;
                    video.pause();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }, {&lt;br /&gt;
            threshold: 0.5  // play when 50% visible&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        videos.forEach( function ( video ) {&lt;br /&gt;
            video.muted = true;        // required for autoplay in most browsers&lt;br /&gt;
            video.loop = true;          // infinite loop&lt;br /&gt;
            video.playsInline = true;   // iOS Safari support&lt;br /&gt;
            observer.observe( video );&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if ( document.readyState !== &#039;loading&#039; ) {&lt;br /&gt;
        setupScrollVideos();&lt;br /&gt;
    } else {&lt;br /&gt;
        document.addEventListener( &#039;DOMContentLoaded&#039;, setupScrollVideos );&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
} )();&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function addPdfButton() {&lt;br /&gt;
    /* Chỉ hiện nút trên page Datasheet hoặc User Guide */&lt;br /&gt;
    var pageName = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgPageName&amp;quot;)) || document.title;&lt;br /&gt;
    pageName = pageName.replace(/_/g, &amp;quot; &amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
    var allowedSuffixes = [&amp;quot; Datasheet&amp;quot;, &amp;quot; User Guide&amp;quot;];&lt;br /&gt;
    var shouldShow = allowedSuffixes.some(function (suffix) {&lt;br /&gt;
        return pageName.endsWith(suffix);&lt;br /&gt;
    });&lt;br /&gt;
    if (!shouldShow) return;&lt;br /&gt;
    &lt;br /&gt;
    /* Phần code tạo button cũ giữ nguyên bên dưới */&lt;br /&gt;
    var heading = document.querySelector(&amp;quot;.mw-first-heading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;#firstHeading&amp;quot;) ||&lt;br /&gt;
                  document.querySelector(&amp;quot;h1.firstHeading&amp;quot;);&lt;br /&gt;
    if (!heading || document.getElementById(&amp;quot;soji-pdf-btn&amp;quot;)) return;&lt;br /&gt;
&lt;br /&gt;
    var btn = document.createElement(&amp;quot;button&amp;quot;);&lt;br /&gt;
    btn.id = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.className = &amp;quot;soji-pdf-btn&amp;quot;;&lt;br /&gt;
    btn.title = &amp;quot;Download this page as PDF&amp;quot;;&lt;br /&gt;
    btn.innerHTML =&lt;br /&gt;
        &#039;&amp;lt;svg width=&amp;quot;16&amp;quot; height=&amp;quot;16&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot; fill=&amp;quot;none&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke=&amp;quot;currentColor&amp;quot; stroke-width=&amp;quot;2&amp;quot; stroke-linecap=&amp;quot;round&amp;quot; &#039; +&lt;br /&gt;
        &#039;stroke-linejoin=&amp;quot;round&amp;quot; style=&amp;quot;vertical-align:middle;margin-right:6px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;path d=&amp;quot;M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;polyline points=&amp;quot;7 10 12 15 17 10&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;line x1=&amp;quot;12&amp;quot; y1=&amp;quot;15&amp;quot; x2=&amp;quot;12&amp;quot; y2=&amp;quot;3&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/svg&amp;gt;Download PDF&#039;;&lt;br /&gt;
&lt;br /&gt;
    btn.addEventListener(&amp;quot;click&amp;quot;, function () {&lt;br /&gt;
        /* ... click handler giữ nguyên (kèm logic hide Related Documents / Revision History) ... */&lt;br /&gt;
        var SECTIONS_TO_HIDE = [&amp;quot;Related Documents&amp;quot;, &amp;quot;Revision History&amp;quot;];&lt;br /&gt;
        var tagged = [];&lt;br /&gt;
        SECTIONS_TO_HIDE.forEach(function (sectionName) {&lt;br /&gt;
            var headings = document.querySelectorAll(&amp;quot;h2, .mw-heading2&amp;quot;);&lt;br /&gt;
            for (var i = 0; i &amp;lt; headings.length; i++) {&lt;br /&gt;
                var h = headings[i];&lt;br /&gt;
                var text = h.textContent.replace(/\[\s*edit.*?\]/gi, &amp;quot;&amp;quot;).trim();&lt;br /&gt;
                if (text.toLowerCase() === sectionName.toLowerCase()) {&lt;br /&gt;
                    var startEl = h.closest(&amp;quot;div.mw-heading&amp;quot;) || h;&lt;br /&gt;
                    var cur = startEl;&lt;br /&gt;
                    while (cur) {&lt;br /&gt;
                        cur.classList.add(&amp;quot;soji-print-hide&amp;quot;);&lt;br /&gt;
                        tagged.push(cur);&lt;br /&gt;
                        cur = cur.nextElementSibling;&lt;br /&gt;
                        if (!cur) break;&lt;br /&gt;
                        if (cur.matches(&amp;quot;h1, h2&amp;quot;) ||&lt;br /&gt;
                            cur.matches(&amp;quot;div.mw-heading2, div.mw-heading1&amp;quot;) ||&lt;br /&gt;
                            (cur.querySelector &amp;amp;&amp;amp; cur.querySelector(&amp;quot;:scope &amp;gt; h1, :scope &amp;gt; h2&amp;quot;))) {&lt;br /&gt;
                            break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    break;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        var pn = (window.mw &amp;amp;&amp;amp; mw.config.get(&amp;quot;wgTitle&amp;quot;)) || document.title;&lt;br /&gt;
        var originalTitle = document.title;&lt;br /&gt;
        document.title = pn + &amp;quot; - SOJI Wiki&amp;quot;;&lt;br /&gt;
        window.print();&lt;br /&gt;
        setTimeout(function () {&lt;br /&gt;
            tagged.forEach(function (el) { el.classList.remove(&amp;quot;soji-print-hide&amp;quot;); });&lt;br /&gt;
            document.title = originalTitle;&lt;br /&gt;
        }, 500);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    heading.appendChild(btn);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, addPdfButton);&lt;br /&gt;
    } else {&lt;br /&gt;
        addPdfButton();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE - hiện thumbnail thay vì màn hình đen&lt;br /&gt;
   ========================= */&lt;br /&gt;
(function () {&lt;br /&gt;
    function initYouTubeFacade() {&lt;br /&gt;
        var iframes = document.querySelectorAll(&lt;br /&gt;
            &#039;iframe[src*=&amp;quot;youtube.com/embed/&amp;quot;], iframe[src*=&amp;quot;youtube-nocookie.com/embed/&amp;quot;]&#039;&lt;br /&gt;
        );&lt;br /&gt;
        iframes.forEach(function (iframe) {&lt;br /&gt;
            var match = iframe.src.match(/\/embed\/([^?&amp;amp;\/]+)/);&lt;br /&gt;
            if (!match) return;&lt;br /&gt;
            var videoId = match[1];&lt;br /&gt;
&lt;br /&gt;
            var width = iframe.getAttribute(&amp;quot;width&amp;quot;) || iframe.width || 640;&lt;br /&gt;
            var height = iframe.getAttribute(&amp;quot;height&amp;quot;) || iframe.height || 360;&lt;br /&gt;
            var allow = iframe.getAttribute(&amp;quot;allow&amp;quot;) || &lt;br /&gt;
                        &amp;quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
            var facade = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
            facade.className = &amp;quot;soji-yt-facade&amp;quot;;&lt;br /&gt;
            facade.style.maxWidth = width + &amp;quot;px&amp;quot;;&lt;br /&gt;
            facade.dataset.videoId = videoId;&lt;br /&gt;
            facade.dataset.width = width;&lt;br /&gt;
            facade.dataset.height = height;&lt;br /&gt;
            facade.dataset.allow = allow;&lt;br /&gt;
            facade.setAttribute(&amp;quot;role&amp;quot;, &amp;quot;button&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;tabindex&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
            facade.setAttribute(&amp;quot;aria-label&amp;quot;, &amp;quot;Play video&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
            facade.innerHTML =&lt;br /&gt;
                &#039;&amp;lt;img class=&amp;quot;soji-yt-thumb&amp;quot; &#039; +&lt;br /&gt;
                &#039;src=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/hqdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;data-hires=&amp;quot;https://i.ytimg.com/vi/&#039; + videoId + &#039;/maxresdefault.jpg&amp;quot; &#039; +&lt;br /&gt;
                &#039;alt=&amp;quot;Video thumbnail&amp;quot; loading=&amp;quot;lazy&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;button class=&amp;quot;soji-yt-play&amp;quot; aria-label=&amp;quot;Play&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;svg viewBox=&amp;quot;0 0 68 48&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55c-2.93.78-4.63 3.26-5.42 6.19C.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24s-.06-10.95-1.48-16.26z&amp;quot; class=&amp;quot;soji-yt-play-bg&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;path d=&amp;quot;M45 24 27 14v20&amp;quot; fill=&amp;quot;#fff&amp;quot;/&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/svg&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/button&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
            /* Try loading hi-res thumbnail; fall back to hqdefault if fail */&lt;br /&gt;
            var thumb = facade.querySelector(&amp;quot;.soji-yt-thumb&amp;quot;);&lt;br /&gt;
            var hires = thumb.dataset.hires;&lt;br /&gt;
            var test = new Image();&lt;br /&gt;
            test.onload = function () {&lt;br /&gt;
                if (test.width &amp;gt; 320) thumb.src = hires;&lt;br /&gt;
            };&lt;br /&gt;
            test.src = hires;&lt;br /&gt;
&lt;br /&gt;
            function playVideo() {&lt;br /&gt;
                var realIframe = document.createElement(&amp;quot;iframe&amp;quot;);&lt;br /&gt;
                realIframe.src = &amp;quot;https://www.youtube.com/embed/&amp;quot; + videoId + &amp;quot;?autoplay=1&amp;amp;rel=0&amp;quot;;&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;width&amp;quot;, width);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;height&amp;quot;, height);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;frameborder&amp;quot;, &amp;quot;0&amp;quot;);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allow&amp;quot;, allow);&lt;br /&gt;
                realIframe.setAttribute(&amp;quot;allowfullscreen&amp;quot;, &amp;quot;true&amp;quot;);&lt;br /&gt;
                facade.innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
                facade.appendChild(realIframe);&lt;br /&gt;
                facade.classList.add(&amp;quot;soji-yt-playing&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            facade.addEventListener(&amp;quot;click&amp;quot;, playVideo);&lt;br /&gt;
            facade.addEventListener(&amp;quot;keydown&amp;quot;, function (e) {&lt;br /&gt;
                if (e.key === &amp;quot;Enter&amp;quot; || e.key === &amp;quot; &amp;quot;) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    playVideo();&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            iframe.parentNode.replaceChild(facade, iframe);&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (document.readyState === &amp;quot;loading&amp;quot;) {&lt;br /&gt;
        document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, initYouTubeFacade);&lt;br /&gt;
    } else {&lt;br /&gt;
        initYouTubeFacade();&lt;br /&gt;
    }&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1191</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1191"/>
		<updated>2026-05-22T06:39:33Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update footer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link,&lt;br /&gt;
.soji-footer-link:visited,&lt;br /&gt;
.soji-footer-link:link,&lt;br /&gt;
.soji-footer-link:active {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 320px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Bỏ hover effect trên card (không border, không shadow, không transform) */&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pass clicks through icon và description xuống stretched link */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-desc,&lt;br /&gt;
.main-page-product-no-icon {&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link giữ pointer-events bình thường */&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    pointer-events: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chỉ highlight title khi hover card (giống 4 category cards bottom) */&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1190</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1190"/>
		<updated>2026-05-22T05:03:54Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update message no icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
| &amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;&lt;br /&gt;
No icon&amp;lt;br&amp;gt;&lt;br /&gt;
Upload icon with name:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:11px; white-space:nowrap;&amp;quot;&amp;gt;{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{#lst:{{{name|{{PAGENAME}}}}}|product-desc}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1189</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1189"/>
		<updated>2026-05-22T05:00:29Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update message no icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
|&amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;&lt;br /&gt;
No icon&amp;lt;br&amp;gt;&lt;br /&gt;
Upload icon with name:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{#lst:{{{name|{{PAGENAME}}}}}|product-desc}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1186</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1186"/>
		<updated>2026-05-22T04:31:41Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.svg|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
|&amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;📦&amp;lt;br&amp;gt;{{{name|{{PAGENAME}}}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{#lst:{{{name|{{PAGENAME}}}}}|product-desc}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1183</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1183"/>
		<updated>2026-05-22T02:18:36Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update icon&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.png&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-icon.png|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
|&amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;📦&amp;lt;br&amp;gt;{{{name|{{PAGENAME}}}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{#lst:{{{name|{{PAGENAME}}}}}|product-desc}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1182</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1182"/>
		<updated>2026-05-22T02:14:53Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update Main Page Card&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 320px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Bỏ hover effect trên card (không border, không shadow, không transform) */&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pass clicks through icon và description xuống stretched link */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-desc,&lt;br /&gt;
.main-page-product-no-icon {&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link giữ pointer-events bình thường */&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    pointer-events: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chỉ highlight title khi hover card (giống 4 category cards bottom) */&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1181</id>
		<title>LIGO AIR</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1181"/>
		<updated>2026-05-22T02:10:19Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update desc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;Wireless 2.4 GHz fuel sensor for diesel/gasoline tanks, designed for harsh environments (−40°C to +85°C).&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO AIR Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO AIR User Guide|User Guide]]&lt;br /&gt;
* [[LIGO AIR Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO AIR Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO AIR Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO AIR Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO AIR Video|Video]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:LIGO-AIR-product-overview.png|320px|center|LIGO AIR]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 4px;&amp;quot;&amp;gt;LIGO AIR&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1180</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1180"/>
		<updated>2026-05-22T02:05:10Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update Main Page Card&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 280px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Bỏ hover effect trên card (không border, không shadow, không transform) */&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    box-shadow: none;&lt;br /&gt;
    transform: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pass clicks through icon và description xuống stretched link */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-desc,&lt;br /&gt;
.main-page-product-no-icon {&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link giữ pointer-events bình thường */&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    pointer-events: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chỉ highlight title khi hover card (giống 4 category cards bottom) */&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1179</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1179"/>
		<updated>2026-05-22T02:01:27Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update Main Page Card&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 280px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    border-color: #2c5aa0;&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(44, 90, 160, 0.12);&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    bottom: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo các phần khác hiển thị nhưng link cover phía trên */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-title,&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    z-index: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nếu có link khác trong card (vd icon có link riêng), giữ nó clickable trên cùng */&lt;br /&gt;
.main-page-product-card a:not(.main-page-product-title a) {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    z-index: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
    color: #1a3a6e;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_PRO&amp;diff=1178</id>
		<title>LIGO PRO</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_PRO&amp;diff=1178"/>
		<updated>2026-05-22T01:47:09Z</updated>

		<summary type="html">&lt;p&gt;Admin: Initial page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;Descriptions&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO PRO Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO PRO User Guide|User Guide]]&lt;br /&gt;
* [[LIGO PRO Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO PRO Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO PRO Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO PRO Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO PRO Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:LIGO PRO| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:LIGO PRO| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:LIGO PRO| |-}}-Product-overview.png|320px|frameless|LIGO PRO]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:LIGO PRO| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;LIGO PRO&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Category:LIGO_PRO&amp;diff=1177</id>
		<title>Category:LIGO PRO</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Category:LIGO_PRO&amp;diff=1177"/>
		<updated>2026-05-22T01:46:21Z</updated>

		<summary type="html">&lt;p&gt;Admin: Auto-created category for LIGO PRO&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!-- auto-created category --&amp;gt;&lt;br /&gt;
{{DEFAULTSORT:5 LIGO PRO}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_PRO&amp;diff=1176</id>
		<title>LIGO PRO</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_PRO&amp;diff=1176"/>
		<updated>2026-05-22T01:46:21Z</updated>

		<summary type="html">&lt;p&gt;Admin: Create page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;{{Placeholder|Brief description of LIGO PRO}}&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO PRO Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO PRO User Guide|User Guide]]&lt;br /&gt;
* [[LIGO PRO Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO PRO Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO PRO Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO PRO Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO PRO Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:LIGO PRO| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:LIGO PRO| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:LIGO PRO| |-}}-Product-overview.png|320px|frameless|LIGO PRO]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:LIGO PRO| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;LIGO PRO&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1175</id>
		<title>LIGO AIR</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1175"/>
		<updated>2026-05-22T01:45:37Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update desc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;Wireless fuel level Wireless fuel level sensor with Bluetooth 5.4 and ultra-low power (9 µA). Designed for vehicles, marine vessels, and industrial tanks with IP69K protection.&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO AIR Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO AIR User Guide|User Guide]]&lt;br /&gt;
* [[LIGO AIR Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO AIR Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO AIR Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO AIR Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO AIR Video|Video]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:LIGO-AIR-product-overview.png|320px|center|LIGO AIR]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 4px;&amp;quot;&amp;gt;LIGO AIR&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1173</id>
		<title>LIGO AIR</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1173"/>
		<updated>2026-05-22T01:41:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;Wireless fuel level sensor with Bluetooth Low Energy 5.4, ultra-low power consumption (9 µA), 8-10 years battery life, IP69K protection, designed for fuel level measurement in vehicle tanks, marine vessels, and industrial fuel storage.&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO AIR Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO AIR User Guide|User Guide]]&lt;br /&gt;
* [[LIGO AIR Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO AIR Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO AIR Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO AIR Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO AIR Video|Video]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:LIGO-AIR-product-overview.png|320px|center|LIGO AIR]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 4px;&amp;quot;&amp;gt;LIGO AIR&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1172</id>
		<title>Template:Boilerplate-ProductPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1172"/>
		<updated>2026-05-22T01:38:38Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Boilerplate for product pages.&lt;br /&gt;
[[Category:Boilerplates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;div class=&amp;quot;product-page-desc&amp;quot;&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;{{Placeholder|Brief description of {{subst:PAGENAME}}}}&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[{{subst:PAGENAME}} Datasheet|Datasheet]]&lt;br /&gt;
* [[{{subst:PAGENAME}} User Guide|User Guide]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Promotional Material|Promotional Material]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:{{subst:PAGENAME}}| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png|320px|frameless|{{subst:PAGENAME}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;{{subst:PAGENAME}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1166</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1166"/>
		<updated>2026-05-22T01:28:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-overview.png&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-overview.png|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
|&amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;📦&amp;lt;br&amp;gt;{{{name|{{PAGENAME}}}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{#lst:{{{name|{{PAGENAME}}}}}|product-desc}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1165</id>
		<title>Template:Boilerplate-ProductPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1165"/>
		<updated>2026-05-22T01:27:37Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Boilerplate for product pages.&lt;br /&gt;
[[Category:Boilerplates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;section begin=&amp;quot;product-desc&amp;quot; /&amp;gt;{{Placeholder|e.g., Brief description of {{subst:PAGENAME}}: what it is, primary function, key features, target use case. Edit this page to replace this hint with your actual product description (1–2 paragraphs).}}&amp;lt;section end=&amp;quot;product-desc&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[{{subst:PAGENAME}} Datasheet|Datasheet]]&lt;br /&gt;
* [[{{subst:PAGENAME}} User Guide|User Guide]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Promotional Material|Promotional Material]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:{{subst:PAGENAME}}| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png|320px|frameless|{{subst:PAGENAME}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;{{subst:PAGENAME}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1164</id>
		<title>Template:Boilerplate-ProductPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1164"/>
		<updated>2026-05-22T01:19:43Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Boilerplate for product pages.&lt;br /&gt;
[[Category:Boilerplates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;&amp;lt;onlyinclude&amp;gt;{{Placeholder|e.g., Brief description of {{subst:PAGENAME}}: what it is, primary function, key features, target use case. Edit this page to replace this hint with your actual product description (1–2 paragraphs).}}&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[{{subst:PAGENAME}} Datasheet|Datasheet]]&lt;br /&gt;
* [[{{subst:PAGENAME}} User Guide|User Guide]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Promotional Material|Promotional Material]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:{{subst:PAGENAME}}| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png|320px|frameless|{{subst:PAGENAME}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;{{subst:PAGENAME}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1163</id>
		<title>Template:MainPageProductCard</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:MainPageProductCard&amp;diff=1163"/>
		<updated>2026-05-22T01:18:40Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;onlyinclude&amp;gt;&amp;lt;div class=&amp;quot;main-page-product-card&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-icon&amp;quot;&amp;gt;{{#ifexist:File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-overview.png&lt;br /&gt;
|[[File:{{#replace:{{{name|{{PAGENAME}}}}}| |-}}-Product-overview.png|160px|link={{{name|{{PAGENAME}}}}}]]&lt;br /&gt;
|&amp;lt;div class=&amp;quot;main-page-product-no-icon&amp;quot;&amp;gt;📦&amp;lt;br&amp;gt;{{{name|{{PAGENAME}}}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-title&amp;quot;&amp;gt;[[{{{name|{{PAGENAME}}}}}|{{{name|{{PAGENAME}}}}}]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-product-desc&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist:{{{name|{{PAGENAME}}}}}&lt;br /&gt;
 | {{:{{{name|{{PAGENAME}}}}}}}&lt;br /&gt;
 | {{{desc|}}}&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Usage: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;{{MainPageProductCard|name=LIGO AIR}}&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
Add description per product via #switch above.&lt;br /&gt;
[[Category:Templates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1162</id>
		<title>LIGO AIR</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1162"/>
		<updated>2026-05-22T01:17:13Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;onlyinclude&amp;gt;Wireless fuel level sensor with Bluetooth Low Energy 5.4, ultra-low power consumption (9 µA), 8-10 years battery life, IP69K protection, designed for fuel level measurement in vehicle tanks, marine vessels, and industrial fuel storage.&amp;lt;/onlyinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[LIGO AIR Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO AIR User Guide|User Guide]]&lt;br /&gt;
* [[LIGO AIR Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO AIR Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO AIR Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO AIR Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO AIR Video|Video]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:LIGO-AIR-product-overview.png|320px|center|LIGO AIR]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 4px;&amp;quot;&amp;gt;LIGO AIR&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1161</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1161"/>
		<updated>2026-05-22T01:10:31Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&#039;&#039;&#039;Welcome to the SOJI Electronics Wiki!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Find technical resources, product documentation, configuration guides, and compatibility information for all SOJI Electronics products below, or use the search bar to find specific information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-products-grid&amp;quot;&amp;gt;&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|category=Products&lt;br /&gt;
|namespace=main&lt;br /&gt;
|mode=userformat&lt;br /&gt;
|format=,{{MainPageProductCard{{!}}name=%PAGE%}},,&lt;br /&gt;
|ordermethod=title&lt;br /&gt;
|order=ascending&lt;br /&gt;
|allowcachedresults=false&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;categories-list categories-list-4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = info&lt;br /&gt;
| link  = General Information&lt;br /&gt;
| icon  = Icon-info.svg&lt;br /&gt;
| title = General Information&lt;br /&gt;
| desc  = Reference documentation, integration guides, protocol descriptions, and platform compatibility.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = app&lt;br /&gt;
| link  = Software &amp;amp; Applications&lt;br /&gt;
| icon  = Icon-software.svg&lt;br /&gt;
| title = Software &amp;amp; Applications&lt;br /&gt;
| desc  = Mobile applications, configurator tools, and integration software for managing SOJI devices.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = accessories&lt;br /&gt;
| link  = Accessories&lt;br /&gt;
| icon  = Icon-accessories.svg&lt;br /&gt;
| title = Accessories&lt;br /&gt;
| desc  = Adapters, cables, mounting kits, and signal boosters for SOJI sensor systems.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = faq&lt;br /&gt;
| link  = Frequently Asked Questions - FAQ&lt;br /&gt;
| icon  = Icon-faq.svg&lt;br /&gt;
| title = FAQ&lt;br /&gt;
| desc  = Common questions about installation, configuration, troubleshooting, and product compatibility.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;© 2026 SOJI Electronics JSC. All Rights Reserved.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:CategoryBlock&amp;diff=1160</id>
		<title>Template:CategoryBlock</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:CategoryBlock&amp;diff=1160"/>
		<updated>2026-05-22T01:09:31Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;category-block&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;category-block-header&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;category-block-icon&amp;quot;&amp;gt;[[File:{{{icon|Icon-default.svg}}}|56px|link={{{link|{{{title}}}}}}]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;category-block-title&amp;quot;&amp;gt;&#039;&#039;&#039;[[{{{link|{{{title}}}}}}|{{{title}}}]]&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;category-block-desc&amp;quot;&amp;gt;{{{desc}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1157</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1157"/>
		<updated>2026-05-21T11:07:37Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&#039;&#039;&#039;Welcome to the SOJI Electronics Wiki!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Find technical resources, product documentation, configuration guides, and compatibility information for all SOJI Electronics products below, or use the search bar to find specific information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-products-grid&amp;quot;&amp;gt;&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|category=Products&lt;br /&gt;
|namespace=main&lt;br /&gt;
|mode=userformat&lt;br /&gt;
|format=,{{MainPageProductCard{{!}}name=%PAGE%}},,&lt;br /&gt;
|ordermethod=title&lt;br /&gt;
|order=ascending&lt;br /&gt;
|allowcachedresults=false&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;categories-list categories-list-4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = info&lt;br /&gt;
| link  = General Information&lt;br /&gt;
| icon  = Icon-info.svg&lt;br /&gt;
| title = General Information&lt;br /&gt;
| desc  = Reference documentation, integration guides, protocol descriptions, and platform compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[LIGO Air Configuration|BLE Protocol Integration]] — Advertising message format&lt;br /&gt;
* [[Compatibility|Platform Compatibility]] — Tested telematics platforms&lt;br /&gt;
* Firmware version history&lt;br /&gt;
* Product Change Notifications (PCN)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = app&lt;br /&gt;
| link  = Software &amp;amp; Applications&lt;br /&gt;
| icon  = Icon-software.svg&lt;br /&gt;
| title = Software &amp;amp; Applications&lt;br /&gt;
| desc  = Mobile applications, configurator tools, and integration software for managing SOJI devices.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Software &amp;amp; Applications|LIGO BLE Configurator]] — iOS / Android&lt;br /&gt;
* Firmware downloads&lt;br /&gt;
* Protocol integration libraries&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = accessories&lt;br /&gt;
| link  = Accessories&lt;br /&gt;
| icon  = Icon-accessories.svg&lt;br /&gt;
| title = Accessories&lt;br /&gt;
| desc  = Adapters, cables, mounting kits, and signal boosters for SOJI sensor systems.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Accessories|LIGO AIR Adapter]] — BLE signal booster for receiver&lt;br /&gt;
* Cable accessories&lt;br /&gt;
* Mounting kits&lt;br /&gt;
* Spare parts&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = faq&lt;br /&gt;
| link  = Frequently Asked Questions - FAQ&lt;br /&gt;
| icon  = Icon-faq.svg&lt;br /&gt;
| title = FAQ&lt;br /&gt;
| desc  = Common questions about installation, configuration, troubleshooting, and product compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Frequently Asked Questions - FAQ|All FAQ topics]]&lt;br /&gt;
* Installation FAQ&lt;br /&gt;
* Configuration FAQ&lt;br /&gt;
* Troubleshooting FAQ&lt;br /&gt;
* Compatibility FAQ&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;© 2026 SOJI Electronics JSC. All Rights Reserved.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1154</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1154"/>
		<updated>2026-05-21T11:05:48Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&#039;&#039;&#039;Welcome to the SOJI Electronics Wiki!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Find technical resources, product documentation, configuration guides, and compatibility information for all SOJI Electronics products below, or use the search bar to find specific information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-products-grid&amp;quot;&amp;gt;&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|category=Products&lt;br /&gt;
|namespace=main&lt;br /&gt;
|mode=userformat&lt;br /&gt;
|format=,{{MainPageProductCard{{!}}name=%PAGE%}},,&lt;br /&gt;
|ordermethod=title&lt;br /&gt;
|order=ascending&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;categories-list categories-list-4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = info&lt;br /&gt;
| link  = General Information&lt;br /&gt;
| icon  = Icon-info.svg&lt;br /&gt;
| title = General Information&lt;br /&gt;
| desc  = Reference documentation, integration guides, protocol descriptions, and platform compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[LIGO Air Configuration|BLE Protocol Integration]] — Advertising message format&lt;br /&gt;
* [[Compatibility|Platform Compatibility]] — Tested telematics platforms&lt;br /&gt;
* Firmware version history&lt;br /&gt;
* Product Change Notifications (PCN)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = app&lt;br /&gt;
| link  = Software &amp;amp; Applications&lt;br /&gt;
| icon  = Icon-software.svg&lt;br /&gt;
| title = Software &amp;amp; Applications&lt;br /&gt;
| desc  = Mobile applications, configurator tools, and integration software for managing SOJI devices.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Software &amp;amp; Applications|LIGO BLE Configurator]] — iOS / Android&lt;br /&gt;
* Firmware downloads&lt;br /&gt;
* Protocol integration libraries&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = accessories&lt;br /&gt;
| link  = Accessories&lt;br /&gt;
| icon  = Icon-accessories.svg&lt;br /&gt;
| title = Accessories&lt;br /&gt;
| desc  = Adapters, cables, mounting kits, and signal boosters for SOJI sensor systems.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Accessories|LIGO AIR Adapter]] — BLE signal booster for receiver&lt;br /&gt;
* Cable accessories&lt;br /&gt;
* Mounting kits&lt;br /&gt;
* Spare parts&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = faq&lt;br /&gt;
| link  = Frequently Asked Questions - FAQ&lt;br /&gt;
| icon  = Icon-faq.svg&lt;br /&gt;
| title = FAQ&lt;br /&gt;
| desc  = Common questions about installation, configuration, troubleshooting, and product compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Frequently Asked Questions - FAQ|All FAQ topics]]&lt;br /&gt;
* Installation FAQ&lt;br /&gt;
* Configuration FAQ&lt;br /&gt;
* Troubleshooting FAQ&lt;br /&gt;
* Compatibility FAQ&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;© 2026 SOJI Electronics JSC. All Rights Reserved.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1151</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1151"/>
		<updated>2026-05-21T11:02:50Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&#039;&#039;&#039;Welcome to the SOJI Electronics Wiki!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Find technical resources, product documentation, configuration guides, and compatibility information for all SOJI Electronics products below, or use the search bar to find specific information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-products-grid&amp;quot;&amp;gt;&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|category=Products&lt;br /&gt;
|namespace=main&lt;br /&gt;
|mode=userformat&lt;br /&gt;
|format=,{{MainPageProductCard{{!}}name=%PAGE%}},,&lt;br /&gt;
|ordermethod=title&lt;br /&gt;
|order=ascending&lt;br /&gt;
|allowcachedresults=false&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;categories-list categories-list-4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = info&lt;br /&gt;
| link  = General Information&lt;br /&gt;
| icon  = Icon-info.svg&lt;br /&gt;
| title = General Information&lt;br /&gt;
| desc  = Reference documentation, integration guides, protocol descriptions, and platform compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[LIGO Air Configuration|BLE Protocol Integration]] — Advertising message format&lt;br /&gt;
* [[Compatibility|Platform Compatibility]] — Tested telematics platforms&lt;br /&gt;
* Firmware version history&lt;br /&gt;
* Product Change Notifications (PCN)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = app&lt;br /&gt;
| link  = Software &amp;amp; Applications&lt;br /&gt;
| icon  = Icon-software.svg&lt;br /&gt;
| title = Software &amp;amp; Applications&lt;br /&gt;
| desc  = Mobile applications, configurator tools, and integration software for managing SOJI devices.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Software &amp;amp; Applications|LIGO BLE Configurator]] — iOS / Android&lt;br /&gt;
* Firmware downloads&lt;br /&gt;
* Protocol integration libraries&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = accessories&lt;br /&gt;
| link  = Accessories&lt;br /&gt;
| icon  = Icon-accessories.svg&lt;br /&gt;
| title = Accessories&lt;br /&gt;
| desc  = Adapters, cables, mounting kits, and signal boosters for SOJI sensor systems.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Accessories|LIGO AIR Adapter]] — BLE signal booster for receiver&lt;br /&gt;
* Cable accessories&lt;br /&gt;
* Mounting kits&lt;br /&gt;
* Spare parts&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = faq&lt;br /&gt;
| link  = Frequently Asked Questions - FAQ&lt;br /&gt;
| icon  = Icon-faq.svg&lt;br /&gt;
| title = FAQ&lt;br /&gt;
| desc  = Common questions about installation, configuration, troubleshooting, and product compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Frequently Asked Questions - FAQ|All FAQ topics]]&lt;br /&gt;
* Installation FAQ&lt;br /&gt;
* Configuration FAQ&lt;br /&gt;
* Troubleshooting FAQ&lt;br /&gt;
* Compatibility FAQ&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;© 2026 SOJI Electronics JSC. All Rights Reserved.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1146</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Main_Page&amp;diff=1146"/>
		<updated>2026-05-21T10:54:18Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&#039;&#039;&#039;Welcome to the SOJI Electronics Wiki!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Find technical resources, product documentation, configuration guides, and compatibility information for all SOJI Electronics products below, or use the search bar to find specific information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;main-page-products-grid&amp;quot;&amp;gt;&lt;br /&gt;
{{#dpl:&lt;br /&gt;
|category=Products&lt;br /&gt;
|namespace=main&lt;br /&gt;
|mode=userformat&lt;br /&gt;
|format=,{{MainPageProductCard{{!}}name=%PAGE%}},,&lt;br /&gt;
|ordermethod=title&lt;br /&gt;
|order=ascending&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;categories-list categories-list-4&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = info&lt;br /&gt;
| link  = General Information&lt;br /&gt;
| icon  = Icon-info.svg&lt;br /&gt;
| title = General Information&lt;br /&gt;
| desc  = Reference documentation, integration guides, protocol descriptions, and platform compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[LIGO Air Configuration|BLE Protocol Integration]] — Advertising message format&lt;br /&gt;
* [[Compatibility|Platform Compatibility]] — Tested telematics platforms&lt;br /&gt;
* Firmware version history&lt;br /&gt;
* Product Change Notifications (PCN)&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = app&lt;br /&gt;
| link  = Software &amp;amp; Applications&lt;br /&gt;
| icon  = Icon-software.svg&lt;br /&gt;
| title = Software &amp;amp; Applications&lt;br /&gt;
| desc  = Mobile applications, configurator tools, and integration software for managing SOJI devices.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Software &amp;amp; Applications|LIGO BLE Configurator]] — iOS / Android&lt;br /&gt;
* Firmware downloads&lt;br /&gt;
* Protocol integration libraries&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = accessories&lt;br /&gt;
| link  = Accessories&lt;br /&gt;
| icon  = Icon-accessories.svg&lt;br /&gt;
| title = Accessories&lt;br /&gt;
| desc  = Adapters, cables, mounting kits, and signal boosters for SOJI sensor systems.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Accessories|LIGO AIR Adapter]] — BLE signal booster for receiver&lt;br /&gt;
* Cable accessories&lt;br /&gt;
* Mounting kits&lt;br /&gt;
* Spare parts&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{CategoryBlock&lt;br /&gt;
| id    = faq&lt;br /&gt;
| link  = Frequently Asked Questions - FAQ&lt;br /&gt;
| icon  = Icon-faq.svg&lt;br /&gt;
| title = FAQ&lt;br /&gt;
| desc  = Common questions about installation, configuration, troubleshooting, and product compatibility.&lt;br /&gt;
| products =&lt;br /&gt;
* [[Frequently Asked Questions - FAQ|All FAQ topics]]&lt;br /&gt;
* Installation FAQ&lt;br /&gt;
* Configuration FAQ&lt;br /&gt;
* Troubleshooting FAQ&lt;br /&gt;
* Compatibility FAQ&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;© 2026 SOJI Electronics JSC. All Rights Reserved.&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1143</id>
		<title>Template:Boilerplate-ProductPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=Template:Boilerplate-ProductPage&amp;diff=1143"/>
		<updated>2026-05-21T10:48:14Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
Boilerplate for product pages.&lt;br /&gt;
[[Category:Boilerplates]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&amp;lt;includeonly&amp;gt;{{Placeholder|e.g., Brief description of {{subst:PAGENAME}}: what it is, primary function, key features, target use case. Edit this page to replace this hint with your actual product description (1–2 paragraphs).}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[{{subst:PAGENAME}} Datasheet|Datasheet]]&lt;br /&gt;
* [[{{subst:PAGENAME}} User Guide|User Guide]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Promotional Material|Promotional Material]]&lt;br /&gt;
* [[{{subst:PAGENAME}} Video|Video]]&lt;br /&gt;
* &amp;lt;span class=&amp;quot;protocol-link&amp;quot;&amp;gt;[[Media:{{#replace:{{subst:PAGENAME}}| |-}}-Protocol.pdf | Protocol]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
{{#ifexist: File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 1px solid #c8ccd1; border-radius: 8px; background: #fff; overflow: hidden; display: flex; align-items: center; justify-content: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png|320px|frameless|{{subst:PAGENAME}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| &amp;lt;div style=&amp;quot;width: 320px; height: 320px; border: 2px dashed #c8ccd1; border-radius: 8px; background: #f8f9fa; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; box-sizing: border-box; text-align: center; color: #54595d;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 2.5em; color: #c8ccd1; margin-bottom: 8px;&amp;quot;&amp;gt;📷&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-weight: bold; font-size: 1em; color: #202122; margin-bottom: 12px;&amp;quot;&amp;gt;No image available&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.85em; line-height: 1.5; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Please upload an image named:&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;code style=&amp;quot;background: #eaecf0; padding: 2px 6px; border-radius: 3px; font-size: 0.9em; word-break: break-all;&amp;quot;&amp;gt;{{#replace:{{subst:PAGENAME}}| |-}}-Product-overview.png&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 0.8em; color: #72777d; margin-bottom: 12px;&amp;quot;&amp;gt;&lt;br /&gt;
Recommended size: &#039;&#039;&#039;320 × 320 px&#039;&#039;&#039; (1:1 ratio)&amp;lt;br&amp;gt;&lt;br /&gt;
Format: PNG with transparent background&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top: 6px;&amp;quot;&amp;gt;&lt;br /&gt;
[[Special:Upload|&amp;lt;span style=&amp;quot;background: #0054A6; color: white; padding: 6px 14px; border-radius: 4px; font-size: 0.85em; text-decoration: none; display: inline-block;&amp;quot;&amp;gt;⬆ Upload image&amp;lt;/span&amp;gt;]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 8px;&amp;quot;&amp;gt;{{subst:PAGENAME}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;br /&gt;
&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1142</id>
		<title>LIGO AIR</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=LIGO_AIR&amp;diff=1142"/>
		<updated>2026-05-21T10:47:16Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;display: flex; gap: 24px; align-items: flex-start;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 1;&amp;quot;&amp;gt;&lt;br /&gt;
Wireless fuel level sensor with Bluetooth Low Energy 5.4, ultra-low power consumption (9 µA), 8-10 years battery life, IP69K protection, designed for fuel level measurement in vehicle tanks, marine vessels, and industrial fuel storage.&lt;br /&gt;
&lt;br /&gt;
* [[LIGO AIR Datasheet|Datasheet]]&lt;br /&gt;
* [[LIGO AIR User Guide|User Guide]]&lt;br /&gt;
* [[LIGO AIR Certification &amp;amp; Approvals|Certifications &amp;amp; Approvals]]&lt;br /&gt;
* [[LIGO AIR Product Change Notifications|Product Change Notifications]]&lt;br /&gt;
* [[LIGO AIR Firmware Changelog|Firmware Changelog]]&lt;br /&gt;
* [[LIGO AIR Promotional Material|Promotional Material]]&lt;br /&gt;
* [[LIGO AIR Video|Video]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex: 0 0 320px;&amp;quot;&amp;gt;&lt;br /&gt;
[[File:LIGO-AIR-product-overview.png|320px|center|LIGO AIR]]&lt;br /&gt;
&amp;lt;div style=&amp;quot;text-align: center; font-size: 0.9em; color: #54595d; margin-top: 4px;&amp;quot;&amp;gt;LIGO AIR&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[Category:Main Page]]&lt;br /&gt;
[[Category:Products]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1136</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.sojielectronics.com/index.php?title=MediaWiki:Common.css&amp;diff=1136"/>
		<updated>2026-05-21T10:34:30Z</updated>

		<summary type="html">&lt;p&gt;Admin: Update color footer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* 1. Layout dòng Item */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeItem {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    padding: 10px 30px 10px 0 !important;&lt;br /&gt;
    border-bottom: 1px solid #e7eaf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Cấu hình Bullet chứa mũi tên */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeBullet {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    right: 0 !important; /* Đẩy sát lề phải */&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    transform: translateY(-50%) !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
    width: 24px !important;&lt;br /&gt;
    height: 24px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chúng ta dùng visibility: hidden để giữ chức năng click nhưng ẩn hình tam giác */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle {&lt;br /&gt;
    visibility: hidden !important; &lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    height: 100% !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. TỰ VẼ MŨI TÊN MẢNH (Chevron) */&lt;br /&gt;
/* Dùng visibility: visible để hiện lại mũi tên mảnh chúng ta tự vẽ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle::after {&lt;br /&gt;
    content: &#039;&#039; !important;&lt;br /&gt;
    visibility: visible !important;&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    top: 50% !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    width: 8px !important;&lt;br /&gt;
    height: 8px !important;&lt;br /&gt;
    border-right: 1.5px solid #4a5fd2 !important; /* Độ mảnh và màu xanh Teltonika */&lt;br /&gt;
    border-bottom: 1.5px solid #4a5fd2 !important;&lt;br /&gt;
    box-sizing: border-box !important;&lt;br /&gt;
    /* Mặc định xoay sang phải &amp;gt; */&lt;br /&gt;
    transform: translate(-70%, -50%) rotate(45deg) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. XOAY MŨI TÊN KHI MỞ (Trạng thái Expanded) */&lt;br /&gt;
/* MediaWiki khi mở sẽ đổi text từ &amp;quot;►&amp;quot; sang &amp;quot;▼&amp;quot; hoặc đổi onclick, &lt;br /&gt;
   CSS dưới đây bắt theo cấu trúc chung của CategoryTree */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle[onclick*=&amp;quot;collapse&amp;quot;]::after,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeToggle-expanded::after {&lt;br /&gt;
    transform: translate(-50%, -75%) rotate(45deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. ẨN CÁC DẤU CHẤM TRANG LÁ */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreePageBullet,&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeEmptyBullet {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Kiểu chữ nhãn (Label) */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeLabel a {&lt;br /&gt;
    color: #4a5fd2 !important;&lt;br /&gt;
    font-size: 14px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Thụt lề cho các cấp con */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren {&lt;br /&gt;
    padding-left: 20px !important;&lt;br /&gt;
    margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Simple top header style */&lt;br /&gt;
body.skin-vector-2022 .vector-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-header,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header-container,&lt;br /&gt;
body.skin-vector-2022 .vector-sticky-header {&lt;br /&gt;
    background-color: #B5C2CD !important;&lt;br /&gt;
    border-bottom: 0 !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-header {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    padding: 0 24px !important;&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo {&lt;br /&gt;
    min-height: 72px !important;&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    font-size: 24px !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    line-height: 1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-icon {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-user-links a,&lt;br /&gt;
body.skin-vector-2022 #lang-switcher,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* language select: đóng màu trắng, mở ra chữ đen nền trắng */&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 #lang-select option {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    background: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content a span,&lt;br /&gt;
body.skin-vector-2022 .vector-dropdown-content .vector-icon {&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    fill: #202122 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body.skin-vector-2022 .mw-logo-wordmark,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label,&lt;br /&gt;
body.skin-vector-2022 #vector-main-menu-dropdown-label .vector-icon,&lt;br /&gt;
body.skin-vector-2022 .vector-header .vector-user-links-main &amp;gt; div &amp;gt; .vector-menu-content a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #p-vector-user-menu-overflow a,&lt;br /&gt;
body.skin-vector-2022 .vector-header #pt-login-2 a,&lt;br /&gt;
body.skin-vector-2022 #lang-select {&lt;br /&gt;
    color: #1F2A36 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   SOJI CUSTOM FOOTER&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.soji-site-footer {&lt;br /&gt;
    background: #4a5468;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    padding: 50px 0 20px;&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, Roboto, sans-serif;&lt;br /&gt;
    width: 100vw;&lt;br /&gt;
    position: relative;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    right: 50%;&lt;br /&gt;
    margin-left: -50vw;&lt;br /&gt;
    margin-right: -50vw;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Sticky footer: ép footer xuống đáy viewport khi page ngắn */&lt;br /&gt;
html, body {&lt;br /&gt;
    min-height: 100vh;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    background: #f8f9fa !important;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer &amp;gt; .mw-page-container,&lt;br /&gt;
body.has-soji-footer &amp;gt; #mw-page-base,&lt;br /&gt;
body.has-soji-footer &amp;gt; main {&lt;br /&gt;
    flex: 1 0 auto;&lt;br /&gt;
}&lt;br /&gt;
body.has-soji-footer .soji-site-footer {&lt;br /&gt;
    flex-shrink: 0;&lt;br /&gt;
    margin-top: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Shell: full ngang màn hình, chỉ chừa padding 2 bên */&lt;br /&gt;
.soji-footer-shell {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
    padding: 0 80px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: 1.6fr 1fr 1fr 1.2fr;&lt;br /&gt;
    gap: 60px;&lt;br /&gt;
    align-items: start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-company-name {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 16px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact-list {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-contact {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: flex-start;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
    margin-bottom: 14px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon {&lt;br /&gt;
    flex: 0 0 18px;&lt;br /&gt;
    width: 18px;&lt;br /&gt;
    height: 18px;&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-icon svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col h2,&lt;br /&gt;
.soji-footer-subscribe-col h2 {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 0 0 20px;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col ul {&lt;br /&gt;
    list-style: none;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-col li {&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    transition: color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-link:hover {&lt;br /&gt;
    color: #ffffff;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-form {&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: 1px solid #ffffff;&lt;br /&gt;
    padding: 12px 14px;&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input::placeholder {&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-input:focus {&lt;br /&gt;
    outline: none;&lt;br /&gt;
    border-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 12px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 1px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-subscribe-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    gap: 14px;&lt;br /&gt;
    margin-top: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item {&lt;br /&gt;
    width: 34px;&lt;br /&gt;
    height: 34px;&lt;br /&gt;
    border-radius: 50%;&lt;br /&gt;
    background: rgba(255, 255, 255, 0.85);&lt;br /&gt;
    color: #4a5468;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item:hover {&lt;br /&gt;
    background: #ffffff;&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-social-item .soji-footer-icon {&lt;br /&gt;
    width: 20px;&lt;br /&gt;
    height: 20px;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-footer-copy {&lt;br /&gt;
    margin-top: 40px;&lt;br /&gt;
    padding-top: 20px;&lt;br /&gt;
    border-top: 1px solid rgba(255, 255, 255, 0.15);&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    color: rgba(255, 255, 255, 0.7);&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 40px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        gap: 40px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
        gap: 30px;&lt;br /&gt;
    }&lt;br /&gt;
    .soji-footer-shell {&lt;br /&gt;
        padding: 0 25px;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .soji-footer-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn MediaWiki standard footer khi đã có SOJI footer */&lt;br /&gt;
body.has-soji-footer #footer,&lt;br /&gt;
body.has-soji-footer .mw-footer {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   BREADCRUMB&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
.custom-breadcrumb {&lt;br /&gt;
    padding: 8px 0 12px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0;&lt;br /&gt;
    margin-bottom: 1em;&lt;br /&gt;
}&lt;br /&gt;
.custom-breadcrumb a { color: #3366cc; text-decoration: none; }&lt;br /&gt;
.custom-breadcrumb a:hover { text-decoration: underline; }&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Wikitable: zebra rows (default style)        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Row chẵn — màu nền xám nhạt */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(even) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(even) &amp;gt; td {&lt;br /&gt;
    background-color: #f5f7fa;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Row lẻ — màu trắng */&lt;br /&gt;
.wikitable &amp;gt; tr:nth-child(odd) &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:nth-child(odd) &amp;gt; td {&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header giữ style mặc định */&lt;br /&gt;
.wikitable &amp;gt; tr &amp;gt; th,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr &amp;gt; th {&lt;br /&gt;
    background-color: #eaecf0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hover row — highlight nhẹ */&lt;br /&gt;
.wikitable &amp;gt; tr:hover &amp;gt; td,&lt;br /&gt;
.wikitable &amp;gt; * &amp;gt; tr:hover &amp;gt; td {&lt;br /&gt;
    background-color: #eaf3ff;&lt;br /&gt;
    transition: background-color 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Border row nhẹ hơn cho cảm giác clean */&lt;br /&gt;
.wikitable td,&lt;br /&gt;
.wikitable th {&lt;br /&gt;
    border: 1px solid #e1e4e8;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* PDF */&lt;br /&gt;
.pdf-icon {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    opacity: 0.6;&lt;br /&gt;
    margin-left: 2px;&lt;br /&gt;
}&lt;br /&gt;
a:hover .pdf-icon {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Main Page — Teltonika-style (no card borders)*/&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.categories-list {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);    /* 4 cột, gọn như Teltonika */&lt;br /&gt;
    gap: 32px 24px;&lt;br /&gt;
    margin: 36px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 3 cột cho Products */&lt;br /&gt;
.categories-list-3 {&lt;br /&gt;
    grid-template-columns: repeat(3, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Grid 4 cột cho Information */&lt;br /&gt;
.categories-list-4 {&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list-3 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr) !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 700px) {&lt;br /&gt;
    .categories-list-3,&lt;br /&gt;
    .categories-list-4 {&lt;br /&gt;
        grid-template-columns: 1fr !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho separator &amp;lt;hr&amp;gt; giữa 2 section */&lt;br /&gt;
.mw-parser-output &amp;gt; hr {&lt;br /&gt;
    border: 0;&lt;br /&gt;
    border-top: 1px solid #eaecf0;&lt;br /&gt;
    margin: 32px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Title link không underline */&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block {&lt;br /&gt;
    /* ❌ KHÔNG có border, background, shadow */&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Header: icon trên, title dưới */&lt;br /&gt;
.category-block-header {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    flex-direction: column !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    gap: 10px !important;&lt;br /&gt;
    margin-bottom: 8px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon đứng trần — không frame xám */&lt;br /&gt;
.category-block-icon {&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    padding: 0 !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
    height: auto !important;&lt;br /&gt;
    box-shadow: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-icon img {&lt;br /&gt;
    height: 72px !important;&lt;br /&gt;
    width: auto !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-title {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 600 !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-desc {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    margin: 6px 8px 12px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle {&lt;br /&gt;
    margin-top: 8px;&lt;br /&gt;
    padding-top: 0;&lt;br /&gt;
    border-top: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text: xanh + không đậm */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    font-weight: 400 !important;       /* không đậm */&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover .toggle-arrow {&lt;br /&gt;
    border-color: #0d47a1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow — mặc định trỏ xuống (collapsed) */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 7px;&lt;br /&gt;
    height: 7px;&lt;br /&gt;
    border-right: 2px solid #1976d2;&lt;br /&gt;
    border-bottom: 2px solid #1976d2;&lt;br /&gt;
    transform: rotate(45deg);             /* trỏ xuống ⌄ */&lt;br /&gt;
    transition: transform 0.25s ease;&lt;br /&gt;
    margin-top: -4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Khi expanded — xoay lên ⌃ */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;].is-expanded .toggle-arrow {&lt;br /&gt;
    transform: rotate(-135deg);           /* trỏ lên */&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products {&lt;br /&gt;
    margin-top: 14px;&lt;br /&gt;
    padding-top: 12px;&lt;br /&gt;
    border-top: 1px dashed #e1e4e8;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products ul {&lt;br /&gt;
    margin: 6px 0;&lt;br /&gt;
    padding-left: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products li {&lt;br /&gt;
    margin: 5px 0;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-products .mw-collapsible-toggle,&lt;br /&gt;
.category-block-products .mw-collapsible-toggle-default,&lt;br /&gt;
.category-block-products a.mw-collapsible-text {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Responsive */&lt;br /&gt;
@media (max-width: 1200px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: repeat(2, 1fr);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .categories-list {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
    .category-block-desc {&lt;br /&gt;
        min-height: auto;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Document download/view buttons               */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
a.btn-download {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    background: #1976d2;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 0.88em;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    transition: background 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a.btn-download:hover {&lt;br /&gt;
    background: #0d47a1;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Style cho link View (không phải button, chỉ là link icon) */&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download) {&lt;br /&gt;
    color: #1976d2;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
    font-size: 0.92em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
a[href*=&amp;quot;.pdf&amp;quot;][target=&amp;quot;_blank&amp;quot;]:not(.btn-download):hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Global heading styles                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* HEADING (H2) — to, đậm, xanh */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    font-size: 1.55em !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
    margin: 1.3em 0 0.6em !important;&lt;br /&gt;
    padding-bottom: 0.3em !important;&lt;br /&gt;
    border-bottom: 1px solid #eaecf0 !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 1 (H3) — to, không đậm */&lt;br /&gt;
.mw-parser-output h3 {&lt;br /&gt;
    font-size: 1.35em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 1em 0 0.4em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 2 (H4) — to vừa, không đậm */&lt;br /&gt;
.mw-parser-output h4 {&lt;br /&gt;
    font-size: 1.25em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.9em 0 0.35em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 3 (H5) — không đậm */&lt;br /&gt;
.mw-parser-output h5 {&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.85em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* SUB-HEADING 4 (H6) — không đậm, không nghiêng */&lt;br /&gt;
.mw-parser-output h6 {&lt;br /&gt;
    font-size: 1.05em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #202122 !important;&lt;br /&gt;
    margin: 0.8em 0 0.3em !important;&lt;br /&gt;
    padding-bottom: 0 !important;&lt;br /&gt;
    border-bottom: none !important;&lt;br /&gt;
    line-height: 1.3 !important;&lt;br /&gt;
    font-style: normal !important;   /* override Vector default italic */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output .mw-editsection,&lt;br /&gt;
.mw-parser-output .mw-editsection a {&lt;br /&gt;
    font-size: 0.6em !important;&lt;br /&gt;
    font-weight: 400 !important;&lt;br /&gt;
    color: #54595d !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #1976d2 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* TOC: collapse sub-headings by default        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Ẩn mọi sub-list trong TOC mặc định */&lt;br /&gt;
.vector-toc .vector-toc-list .vector-toc-list-item .vector-toc-list {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị khi item được expand */&lt;br /&gt;
.vector-toc .vector-toc-list-item-expanded &amp;gt; .vector-toc-list,&lt;br /&gt;
.vector-toc-toggle[aria-expanded=&amp;quot;true&amp;quot;] ~ .vector-toc-list {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Hiển thị mũi tên ▶ rõ ràng hơn */&lt;br /&gt;
.vector-toc-toggle {&lt;br /&gt;
    opacity: 0.7;&lt;br /&gt;
    transition: opacity 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-toc-toggle:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body, .mw-parser-output, h1, h2, h3, h4, h5, h6 {&lt;br /&gt;
    font-family: -apple-system, BlinkMacSystemFont, &amp;quot;Segoe UI&amp;quot;, &amp;quot;Roboto&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Arial, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Icon SVG render crisp */&lt;br /&gt;
.category-block-icon img,&lt;br /&gt;
img[src*=&amp;quot;Icon-&amp;quot;] {&lt;br /&gt;
    image-rendering: -webkit-optimize-contrast;&lt;br /&gt;
    image-rendering: crisp-edges;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Safety callout tables                        */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger,&lt;br /&gt;
.wikitable.warning,&lt;br /&gt;
.wikitable.caution,&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    border: none;&lt;br /&gt;
    border-left-width: 4px;&lt;br /&gt;
    border-left-style: solid;&lt;br /&gt;
    margin: 16px 0;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-radius: 0 4px 4px 0;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger th,&lt;br /&gt;
.wikitable.warning th,&lt;br /&gt;
.wikitable.caution th,&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    text-align: left !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    padding: 10px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.wikitable.danger td,&lt;br /&gt;
.wikitable.warning td,&lt;br /&gt;
.wikitable.caution td,&lt;br /&gt;
.wikitable.notice td {&lt;br /&gt;
    padding: 12px 16px !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    line-height: 1.55;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* DANGER — Red */&lt;br /&gt;
.wikitable.danger {&lt;br /&gt;
    border-left-color: #d32f2f;&lt;br /&gt;
    background: #ffebee;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.danger th {&lt;br /&gt;
    background: #ffcdd2 !important;&lt;br /&gt;
    color: #b71c1c !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* WARNING — Orange */&lt;br /&gt;
.wikitable.warning {&lt;br /&gt;
    border-left-color: #f57c00;&lt;br /&gt;
    background: #fff3e0;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.warning th {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    color: #e65100 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* CAUTION — Yellow */&lt;br /&gt;
.wikitable.caution {&lt;br /&gt;
    border-left-color: #f9a825;&lt;br /&gt;
    background: #fffde7;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.caution th {&lt;br /&gt;
    background: #fff9c4 !important;&lt;br /&gt;
    color: #f57f17 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* NOTICE — Blue */&lt;br /&gt;
.wikitable.notice {&lt;br /&gt;
    border-left-color: #1976d2;&lt;br /&gt;
    background: #e3f2fd;&lt;br /&gt;
}&lt;br /&gt;
.wikitable.notice th {&lt;br /&gt;
    background: #bbdefb !important;&lt;br /&gt;
    color: #0d47a1 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Pending Reviews Badge */&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    transition: background 0.2s ease, transform 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge:hover {&lt;br /&gt;
    background: #ffe0b2 !important;&lt;br /&gt;
    transform: translateY(-1px);&lt;br /&gt;
    box-shadow: 0 2px 4px rgba(229, 81, 0, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge a:hover {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pendingPulse {&lt;br /&gt;
    0%, 100% { box-shadow: 0 0 0 0 rgba(229, 81, 0, 0.4); }&lt;br /&gt;
    50%      { box-shadow: 0 0 0 4px rgba(229, 81, 0, 0); }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#pending-reviews-badge {&lt;br /&gt;
    animation: pendingPulse 2s infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Download table */&lt;br /&gt;
.doc-downloads {&lt;br /&gt;
    border-collapse: collapse !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    margin: 12px 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td {&lt;br /&gt;
    border: none !important;&lt;br /&gt;
    padding: 6px 12px 6px 0 !important;&lt;br /&gt;
    background: transparent !important;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:first-child {&lt;br /&gt;
    font-weight: 500;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads td:last-child {&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-downloads a:hover {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ===== PCN styles ===== */&lt;br /&gt;
.pcn-page-title {&lt;br /&gt;
    margin: 0 0 12px;&lt;br /&gt;
    padding: 14px 18px;&lt;br /&gt;
    background: linear-gradient(135deg, #4b5f78 0%, #5d728e 100%);&lt;br /&gt;
    color: #fff;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro,&lt;br /&gt;
.pcn-note,&lt;br /&gt;
.pcn-section-card {&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 14px 16px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-intro {&lt;br /&gt;
    background: #f7f9fc;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-note {&lt;br /&gt;
    background: #f4f8fd;&lt;br /&gt;
    border-left: 4px solid #5b84b1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-section-title {&lt;br /&gt;
    margin: 20px 0 10px;&lt;br /&gt;
    padding: 8px 12px;&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    border-left: 4px solid #5d728e;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    border-collapse: collapse;&lt;br /&gt;
    margin: 0 0 18px;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th,&lt;br /&gt;
.pcn-table td {&lt;br /&gt;
    border: 1px solid #d8e0ea;&lt;br /&gt;
    padding: 8px 10px;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table th {&lt;br /&gt;
    background: #eef3f8;&lt;br /&gt;
    color: #243447;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: left;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-table tr:nth-child(even) td {&lt;br /&gt;
    background: #fafbfd;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    min-width: 72px;&lt;br /&gt;
    padding: 3px 10px;&lt;br /&gt;
    border-radius: 999px;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
    letter-spacing: 0.02em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-draft {&lt;br /&gt;
    background: #eef1f5;&lt;br /&gt;
    color: #51606f;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-active {&lt;br /&gt;
    background: #e8f4ec;&lt;br /&gt;
    color: #1d6b3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-implemented {&lt;br /&gt;
    background: #eaf1fb;&lt;br /&gt;
    color: #285ea8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-status-obsolete {&lt;br /&gt;
    background: #f7eaea;&lt;br /&gt;
    color: #a33d3d;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(2, minmax(220px, 1fr));&lt;br /&gt;
    gap: 12px 18px;&lt;br /&gt;
    margin: 0 0 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-item {&lt;br /&gt;
    padding: 10px 12px;&lt;br /&gt;
    border: 1px solid #d9e2ec;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-label {&lt;br /&gt;
    display: block;&lt;br /&gt;
    margin-bottom: 4px;&lt;br /&gt;
    color: #5c6b7a;&lt;br /&gt;
    font-size: 12px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    text-transform: uppercase;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.pcn-meta-value {&lt;br /&gt;
    color: #1f2d3a;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 720px) {&lt;br /&gt;
    .pcn-meta {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Highlight bảng row khi được focus qua URL anchor (#fw-v1.2.0)&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Smooth scroll khi click anchor link */&lt;br /&gt;
html {&lt;br /&gt;
    scroll-behavior: smooth;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Offset top để row không bị che bởi sticky header Vector 2022 */&lt;br /&gt;
.wikitable tr[id] {&lt;br /&gt;
    scroll-margin-top: 80px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight row khi được target */&lt;br /&gt;
.wikitable tr:target {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    box-shadow: inset 4px 0 0 #FFC107, 0 0 12px rgba(255, 193, 7, 0.4);&lt;br /&gt;
    animation: highlightPulse 1.5s ease-out 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Highlight cell trong row được target */&lt;br /&gt;
.wikitable tr:target &amp;gt; td {&lt;br /&gt;
    background-color: #fff8dc !important;&lt;br /&gt;
    transition: background-color 0.3s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Animation pulse khi vừa scroll tới */&lt;br /&gt;
@keyframes highlightPulse {&lt;br /&gt;
    0%   { background-color: #FFD54F !important; }&lt;br /&gt;
    50%  { background-color: #FFECB3 !important; }&lt;br /&gt;
    100% { background-color: #fff8dc !important; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Placeholder text styling — used by {{Placeholder|...}}&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder {&lt;br /&gt;
    color: #888 !important;&lt;br /&gt;
    font-style: italic !important;&lt;br /&gt;
    background: #fffbe6 !important;&lt;br /&gt;
    padding: 3px 8px !important;&lt;br /&gt;
    border-left: 3px solid #ffc107 !important;&lt;br /&gt;
    display: inline-block !important;&lt;br /&gt;
    border-radius: 0 3px 3px 0;&lt;br /&gt;
    transition: opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-placeholder:hover {&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn placeholder khỏi PDF/print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-placeholder {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Version History Row Action Toolbar&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
.fw-row-toolbar {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 4px;&lt;br /&gt;
    right: -2px;&lt;br /&gt;
    display: none;&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    padding: 4px;&lt;br /&gt;
    z-index: 10;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-version-history tr:hover .fw-row-toolbar,&lt;br /&gt;
.fw-version-history tr.fw-row-active .fw-row-toolbar {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn {&lt;br /&gt;
    padding: 4px 10px;&lt;br /&gt;
    margin: 0 2px;&lt;br /&gt;
    border: 1px solid #ccc;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #333;&lt;br /&gt;
    transition: all 0.15s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn:hover {&lt;br /&gt;
    background: #0054A6;&lt;br /&gt;
    color: white;&lt;br /&gt;
    border-color: #003d7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.fw-btn-edit:hover     { background: #2196F3; border-color: #1976D2; }&lt;br /&gt;
.fw-btn-add-above:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
.fw-btn-add-below:hover { background: #4CAF50; border-color: #388E3C; }&lt;br /&gt;
&lt;br /&gt;
/* Row đang hover được nhấn nhẹ */&lt;br /&gt;
.fw-version-history tr:hover {&lt;br /&gt;
    background-color: #f0f8ff !important;&lt;br /&gt;
    cursor: default;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print mode: ẩn toolbar */&lt;br /&gt;
@media print {&lt;br /&gt;
    .fw-row-toolbar {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Dim class — fade any content (text, image, table, link, ...)&lt;br /&gt;
 *  Usage: &amp;lt;div class=&amp;quot;dim&amp;quot;&amp;gt;content&amp;lt;/div&amp;gt; or &amp;lt;span class=&amp;quot;dim&amp;quot;&amp;gt;text&amp;lt;/span&amp;gt;&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
.dim {&lt;br /&gt;
    opacity: 0.4;&lt;br /&gt;
    color: #000;&lt;br /&gt;
    transition: opacity 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
@media print {&lt;br /&gt;
    .dim {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MultiBoilerplate dropdown styling */&lt;br /&gt;
fieldset.boilerplate-fieldset,&lt;br /&gt;
#multiboilerplate-fieldset {&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    background: #f8f9fa;&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
fieldset.boilerplate-fieldset legend,&lt;br /&gt;
#multiboilerplate-fieldset legend {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;],&lt;br /&gt;
#multiboilerplate-select,&lt;br /&gt;
#boilerplate-select {&lt;br /&gt;
    padding: 6px 12px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    background: white;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    min-width: 250px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    transition: border-color 0.2s, box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
select[name=&amp;quot;boilerplate&amp;quot;]:hover,&lt;br /&gt;
#multiboilerplate-select:hover {&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
    box-shadow: 0 0 0 2px rgba(0, 84, 166, 0.15);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mb-loading-indicator {&lt;br /&gt;
    animation: pulse 1s ease-in-out infinite;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes pulse {&lt;br /&gt;
    0%, 100% { opacity: 0.5; }&lt;br /&gt;
    50% { opacity: 1; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Software card styling */&lt;br /&gt;
.software-card {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 240px;&lt;br /&gt;
    padding: 16px;&lt;br /&gt;
    margin: 10px;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    vertical-align: top;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);&lt;br /&gt;
    transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card:hover {&lt;br /&gt;
    transform: translateY(-3px);&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 84, 166, 0.15);&lt;br /&gt;
    border-color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-image {&lt;br /&gt;
    height: 120px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title {&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    font-size: 1.05em;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-title a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-desc {&lt;br /&gt;
    font-size: 0.85em;&lt;br /&gt;
    color: #54595d;&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-list {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 16px;&lt;br /&gt;
    margin: 20px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* No-icon placeholder inside card */&lt;br /&gt;
.software-card-no-icon {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    color: #888;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    padding: 8px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    background: #fafafa;&lt;br /&gt;
    border: 2px dashed #c8ccd1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-emoji {&lt;br /&gt;
    font-size: 2em;&lt;br /&gt;
    color: #c8ccd1;&lt;br /&gt;
    margin-bottom: 6px;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text {&lt;br /&gt;
    line-height: 1.4;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.software-card-no-icon-text code {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.95em;&lt;br /&gt;
    word-break: break-all;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    margin-top: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Certifications page — cert cards */&lt;br /&gt;
.cert-card {&lt;br /&gt;
    padding: 12px 16px;&lt;br /&gt;
    margin: 10px 0;&lt;br /&gt;
    border-radius: 6px;&lt;br /&gt;
    border-left: 4px solid;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    gap: 8px;&lt;br /&gt;
    font-size: 1em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available {&lt;br /&gt;
    background: #e8f5e9;&lt;br /&gt;
    border-left-color: #4CAF50;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-available::before {&lt;br /&gt;
    content: &amp;quot;✅&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing {&lt;br /&gt;
    background: #fff3cd;&lt;br /&gt;
    border-left-color: #ffc107;&lt;br /&gt;
    color: #856404;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card-missing::before {&lt;br /&gt;
    content: &amp;quot;⚠&amp;quot;;&lt;br /&gt;
    font-size: 1.2em;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.cert-card code {&lt;br /&gt;
    background: #fff;&lt;br /&gt;
    padding: 2px 6px;&lt;br /&gt;
    border-radius: 3px;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    border: 1px solid #c8ccd1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ============================================================&lt;br /&gt;
 *  Sidebar category filter — CSS-first to prevent FOUC flash&lt;br /&gt;
 *  Hide non-whitelisted sub-categories before JS runs&lt;br /&gt;
 * ============================================================ */&lt;br /&gt;
&lt;br /&gt;
/* Hide all sub-categories trong CategoryTree first */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Show ONLY whitelisted suffixes — using attribute selectors */&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Datasheet&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;User_Guide&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet .CategoryTreeChildren .CategoryTreeItem:has(a[href*=&amp;quot;Video&amp;quot;]) {&lt;br /&gt;
    display: list-item;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Backup: hide known bad items explicitly */&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Product_Change_Notifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Firmware_Changelog&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Promotional_Material&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certifications&amp;quot;],&lt;br /&gt;
#p-categorytree-portlet a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;] {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Product_Change_Notifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Firmware_Changelog&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Promotional_Material&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certifications&amp;quot;]),&lt;br /&gt;
#p-categorytree-portlet li:has(&amp;gt; a[href*=&amp;quot;Certification_%26_Approvals&amp;quot;]) {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Smooth transition khi sidebar render */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    transition: opacity 0.15s ease;&lt;br /&gt;
}&lt;br /&gt;
/* Prevent sidebar layout shift during navigation */&lt;br /&gt;
#mw-panel,&lt;br /&gt;
#vector-main-menu-pinned-container,&lt;br /&gt;
#p-categorytree-portlet {&lt;br /&gt;
    contain: layout style;&lt;br /&gt;
    min-height: 1px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Skeleton loader for sidebar during load */&lt;br /&gt;
.client-nojs #p-categorytree-portlet,&lt;br /&gt;
body.mw-special #p-categorytree-portlet {&lt;br /&gt;
    /* No loading state on special pages */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Protocol link only — make it look like internal links, no icon */&lt;br /&gt;
.protocol-link a {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 0 !important;&lt;br /&gt;
    padding-left: 0 !important;&lt;br /&gt;
    font-weight: normal !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:visited {&lt;br /&gt;
    color: #0645ad !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link a::after,&lt;br /&gt;
.protocol-link a::before {&lt;br /&gt;
    content: none !important;&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.protocol-link img,&lt;br /&gt;
.protocol-link a + img,&lt;br /&gt;
.protocol-link a ~ img {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   FORCE PAGE CONTAINER FULL VIEWPORT WIDTH&lt;br /&gt;
   ========================= */&lt;br /&gt;
.mw-page-container,&lt;br /&gt;
.mw-page-container-inner {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo content inside cũng stretch theo */&lt;br /&gt;
.mw-content-container,&lt;br /&gt;
.mw-body {&lt;br /&gt;
    max-width: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nhưng cap text-heavy content để dễ đọc (text quá dài 1 dòng khó đọc trên màn hình to) */&lt;br /&gt;
.mw-body-content .mw-parser-output {&lt;br /&gt;
    max-width: 1400px;&lt;br /&gt;
    margin: 0 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   DOWNLOAD PDF BUTTON&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-pdf-btn {&lt;br /&gt;
    background: #f0a830;&lt;br /&gt;
    color: #2d3338;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 8px 16px;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: auto;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    display: inline-flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    transition: background 0.2s;&lt;br /&gt;
    font-family: inherit;&lt;br /&gt;
}&lt;br /&gt;
.mw-first-heading,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    gap: 12px;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:hover {&lt;br /&gt;
    background: #d99425;&lt;br /&gt;
}&lt;br /&gt;
.soji-pdf-btn:focus {&lt;br /&gt;
    outline: 2px solid #2c5aa0;&lt;br /&gt;
    outline-offset: 2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRINT / PDF EXPORT STYLES&lt;br /&gt;
   Applied when user clicks button → window.print()&lt;br /&gt;
   ========================= */&lt;br /&gt;
@media print {&lt;br /&gt;
    /* Ẩn UI elements không thuộc nội dung */&lt;br /&gt;
    .mw-sidebar,&lt;br /&gt;
    #mw-panel,&lt;br /&gt;
    .mw-header,&lt;br /&gt;
    #mw-head,&lt;br /&gt;
    #mw-page-base,&lt;br /&gt;
    .mw-portlet-tb,&lt;br /&gt;
    .mw-portlet-lang,&lt;br /&gt;
    .vector-page-toolbar,&lt;br /&gt;
    .vector-menu-tabs,&lt;br /&gt;
    .vector-pinnable-header,&lt;br /&gt;
    .vector-column-start,&lt;br /&gt;
    .vector-column-end,&lt;br /&gt;
    .vector-sticky-header,&lt;br /&gt;
    .vector-header-container,&lt;br /&gt;
    .mw-table-of-contents-container,&lt;br /&gt;
    .soji-site-footer,&lt;br /&gt;
    #footer,&lt;br /&gt;
    .mw-footer,&lt;br /&gt;
    .mw-footer-container,&lt;br /&gt;
    .soji-pdf-btn,&lt;br /&gt;
    .printfooter,&lt;br /&gt;
    .mw-editsection,&lt;br /&gt;
    #catlinks,&lt;br /&gt;
    .mw-jump-link,&lt;br /&gt;
    .mw-indicators,&lt;br /&gt;
    .custom-breadcrumb,&lt;br /&gt;
    #toc .toctogglecheckbox,&lt;br /&gt;
    .mw-cite-backlink,&lt;br /&gt;
    .noprint {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Reset layout cho clean print */&lt;br /&gt;
    html, body {&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        color: black !important;&lt;br /&gt;
        font-size: 11pt;&lt;br /&gt;
        line-height: 1.5;&lt;br /&gt;
        overflow: visible !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    .mw-page-container,&lt;br /&gt;
    .mw-page-container-inner,&lt;br /&gt;
    .mw-content-container,&lt;br /&gt;
    .mw-body,&lt;br /&gt;
    .mw-body-content,&lt;br /&gt;
    .mw-parser-output {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        background: white !important;&lt;br /&gt;
        box-shadow: none !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Heading hierarchy — h1 &amp;gt; h2 &amp;gt; h3 */&lt;br /&gt;
    .mw-first-heading, #firstHeading, h1.firstHeading {&lt;br /&gt;
        font-size: 24pt !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        border-bottom: 2px solid #2c5aa0;&lt;br /&gt;
        padding-bottom: 8px;&lt;br /&gt;
        margin-bottom: 20px;&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h2,&lt;br /&gt;
    .mw-parser-output h2,&lt;br /&gt;
    div.mw-heading2 h2,&lt;br /&gt;
    h2 {&lt;br /&gt;
        font-size: 18pt !important;&lt;br /&gt;
        font-weight: 600 !important;&lt;br /&gt;
        line-height: 1.3 !important;&lt;br /&gt;
        margin: 0 !important;&lt;br /&gt;
        padding: 0 !important;&lt;br /&gt;
        border: none !important;            /* ← bỏ border ở h2 */&lt;br /&gt;
        color: #2c5aa0 !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Wrapper mw-heading2 có border xanh đậm */&lt;br /&gt;
    div.mw-heading2,&lt;br /&gt;
    .mw-heading.mw-heading2 {&lt;br /&gt;
        border-bottom: 0.75px solid #2c5aa0 !important;  /* ← xanh, dày 2px */&lt;br /&gt;
        padding-bottom: 4pt !important;&lt;br /&gt;
        margin-top: 14pt !important;&lt;br /&gt;
        margin-bottom: 8pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    .mw-body-content h3,&lt;br /&gt;
    .mw-parser-output h3,&lt;br /&gt;
    div.mw-heading3,&lt;br /&gt;
    div.mw-heading3 h3,&lt;br /&gt;
    h3 {&lt;br /&gt;
        font-size: 16pt !important;&lt;br /&gt;
        margin-top: 12pt !important;&lt;br /&gt;
        color: #444 !important;&lt;br /&gt;
    }&lt;br /&gt;
    h4 { font-size: 9pt !important; color: #555 !important; }&lt;br /&gt;
&lt;br /&gt;
    /* Tables: keep on same page, có border */&lt;br /&gt;
    table {&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
        border-collapse: collapse;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th, table.wikitable td {&lt;br /&gt;
        border: 1px solid #999;&lt;br /&gt;
        padding: 6px 10px;&lt;br /&gt;
    }&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f5f5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Images full visible */&lt;br /&gt;
    img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        page-break-inside: avoid;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Hiển thị URL của external link */&lt;br /&gt;
    a[href^=&amp;quot;http&amp;quot;]:not([href*=&amp;quot;sojielectronics.com&amp;quot;])::after {&lt;br /&gt;
        content: &amp;quot; (&amp;quot; attr(href) &amp;quot;)&amp;quot;;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        word-break: break-all;&lt;br /&gt;
    }&lt;br /&gt;
    a[href^=&amp;quot;#&amp;quot;]::after, a[href^=&amp;quot;/&amp;quot;]::after { content: &amp;quot;&amp;quot;; }&lt;br /&gt;
    a {&lt;br /&gt;
        color: #2c5aa0;&lt;br /&gt;
        text-decoration: none;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Page break control */&lt;br /&gt;
    ul, ol { page-break-inside: avoid; }&lt;br /&gt;
    blockquote, figure, pre { page-break-inside: avoid; }&lt;br /&gt;
    p { orphans: 3; widows: 3; }&lt;br /&gt;
&lt;br /&gt;
    /* Page settings — A4 với margin chuẩn */&lt;br /&gt;
    @page {&lt;br /&gt;
        margin: 1.5cm 2cm;&lt;br /&gt;
        size: A4;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* Header chữ nhỏ trên cùng mỗi trang */&lt;br /&gt;
    body::before {&lt;br /&gt;
        content: &amp;quot;SOJI Electronics — Technical Documentation Wiki&amp;quot;;&lt;br /&gt;
        display: block;&lt;br /&gt;
        font-size: 9pt;&lt;br /&gt;
        color: #666;&lt;br /&gt;
        text-align: right;&lt;br /&gt;
        border-bottom: 1px solid #ddd;&lt;br /&gt;
        padding-bottom: 6px;&lt;br /&gt;
        margin-bottom: 14px;&lt;br /&gt;
    }&lt;br /&gt;
    /* =========================&lt;br /&gt;
       IMAGES &amp;amp; CAPTIONS - print&lt;br /&gt;
       ========================= */&lt;br /&gt;
    &lt;br /&gt;
    /* Outer container */&lt;br /&gt;
    div.thumb,&lt;br /&gt;
    figure.thumb,&lt;br /&gt;
    figure.mw-default-size,&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Thumb&amp;quot;],&lt;br /&gt;
    figure[typeof~=&amp;quot;mw:File/Frame&amp;quot;],&lt;br /&gt;
    .thumb,&lt;br /&gt;
    .floatright,&lt;br /&gt;
    .floatleft,&lt;br /&gt;
    .tright,&lt;br /&gt;
    .tleft {&lt;br /&gt;
        float: none !important;&lt;br /&gt;
        clear: both !important;&lt;br /&gt;
        margin: 12pt auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;          /* ← override inline width */&lt;br /&gt;
        max-width: 80% !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Inner container (cái này gây bug — có inline width nhỏ) */&lt;br /&gt;
    .thumbinner,&lt;br /&gt;
    div.thumbinner,&lt;br /&gt;
    figure.thumb &amp;gt; *,&lt;br /&gt;
    .thumb .thumbinner {&lt;br /&gt;
        width: auto !important;          /* ← key fix */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        padding: 6pt !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Image */&lt;br /&gt;
    .thumb img,&lt;br /&gt;
    figure img,&lt;br /&gt;
    .image img,&lt;br /&gt;
    a.image img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
        margin: 0 auto !important;&lt;br /&gt;
        display: block !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Caption — không bị bóp width nữa */&lt;br /&gt;
    .thumbcaption,&lt;br /&gt;
    figcaption,&lt;br /&gt;
    div.thumbcaption {&lt;br /&gt;
        width: auto !important;          /* ← override inline */&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        font-style: italic !important;&lt;br /&gt;
        font-size: 9pt !important;&lt;br /&gt;
        color: #555 !important;&lt;br /&gt;
        margin-top: 4pt !important;&lt;br /&gt;
        padding: 0 6pt !important;&lt;br /&gt;
        white-space: normal !important;   /* ← cho phép wrap bình thường */&lt;br /&gt;
        display: block !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Standalone image (không trong thumb) */&lt;br /&gt;
    img {&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   IMAGE CAPTIONS - căn giữa cho normal view&lt;br /&gt;
   ========================= */&lt;br /&gt;
.thumbcaption,&lt;br /&gt;
.thumbinner .thumbcaption,&lt;br /&gt;
figure figcaption,&lt;br /&gt;
figure .mw-file-description-caption {&lt;br /&gt;
    text-align: center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify (kính lúp) bên cạnh caption nếu muốn */&lt;br /&gt;
.magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn icon magnify/expand ở góc caption */&lt;br /&gt;
.magnify,&lt;br /&gt;
.mw-file-description .magnify,&lt;br /&gt;
.thumbcaption .magnify {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
.thumb a,&lt;br /&gt;
.image {&lt;br /&gt;
    pointer-events: none !important;&lt;br /&gt;
    cursor: default !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   YOUTUBE FACADE&lt;br /&gt;
   ========================= */&lt;br /&gt;
.soji-yt-facade {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    aspect-ratio: 16 / 9;&lt;br /&gt;
    background: #000;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin: 12px auto;&lt;br /&gt;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);&lt;br /&gt;
    transition: box-shadow 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover {&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-thumb {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    object-fit: cover;&lt;br /&gt;
    display: block;&lt;br /&gt;
    transition: transform 0.3s, filter 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-thumb {&lt;br /&gt;
    transform: scale(1.02);&lt;br /&gt;
    filter: brightness(0.85);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 50%;&lt;br /&gt;
    left: 50%;&lt;br /&gt;
    transform: translate(-50%, -50%);&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    width: 84px;&lt;br /&gt;
    height: 60px;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    transition: transform 0.2s;&lt;br /&gt;
    pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play svg {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.4));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-play-bg {&lt;br /&gt;
    fill: #212121;&lt;br /&gt;
    fill-opacity: 0.8;&lt;br /&gt;
    transition: fill 0.2s, fill-opacity 0.2s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play {&lt;br /&gt;
    transform: translate(-50%, -50%) scale(1.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-facade:hover .soji-yt-play-bg {&lt;br /&gt;
    fill: #ff0000;&lt;br /&gt;
    fill-opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.soji-yt-playing iframe {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    height: 100%;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    inset: 0;&lt;br /&gt;
    border: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ẩn trong print */&lt;br /&gt;
@media print {&lt;br /&gt;
    .soji-yt-facade,&lt;br /&gt;
    iframe[src*=&amp;quot;youtube&amp;quot;] {&lt;br /&gt;
        display: none !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   TABLES - full width đồng đều&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Page view */&lt;br /&gt;
table.wikitable,&lt;br /&gt;
.mw-parser-output table.wikitable {&lt;br /&gt;
    width: 100%;&lt;br /&gt;
    table-layout: auto;       /* Cell vẫn tự cỡ theo content, nhưng tổng = 100% */&lt;br /&gt;
    margin: 12px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Print/PDF */&lt;br /&gt;
@media print {&lt;br /&gt;
    table,&lt;br /&gt;
    table.wikitable,&lt;br /&gt;
    .mw-parser-output table {&lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
        table-layout: auto !important;&lt;br /&gt;
        margin: 8pt 0 !important;&lt;br /&gt;
        page-break-inside: avoid !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Cell padding rộng hơn để text breathing room */&lt;br /&gt;
    table.wikitable th,&lt;br /&gt;
    table.wikitable td {&lt;br /&gt;
        padding: 6pt 10pt !important;&lt;br /&gt;
        vertical-align: middle !important;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* Header row đậm hơn */&lt;br /&gt;
    table.wikitable th {&lt;br /&gt;
        background: #f5f7fa !important;&lt;br /&gt;
        font-weight: 700 !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;        /* ← căn giữa cụm */&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    flex: 0 0 280px;                 /* ← fixed width 280px, không co dãn */&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    border-color: #2c5aa0;&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(44, 90, 160, 0.12);&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 20px;            /* ← căn giữa horizontal */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
    margin: 0 auto;                  /* ← căn giữa nếu ảnh nhỏ hơn container */&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-top: 12px;                /* ← đẩy title xuống cách image */&lt;br /&gt;
    margin-bottom: 16px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    width: 100%;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;              /* ← căn giữa text */&lt;br /&gt;
    margin: 0;&lt;br /&gt;
    padding: 0 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid (bottom) */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    min-height: 60px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-link a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    font-weight: 600;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 900px) {&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@media (max-width: 600px) {&lt;br /&gt;
    .main-page-products-grid,&lt;br /&gt;
    .main-page-categories-grid {&lt;br /&gt;
        grid-template-columns: 1fr;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* =========================&lt;br /&gt;
   PRODUCT PAGES — Summary card + Full layout&lt;br /&gt;
   ========================= */&lt;br /&gt;
&lt;br /&gt;
/* Direct view: hide summary card (because description shows on Main Page card),&lt;br /&gt;
   show full layout (sub-page links + image) */&lt;br /&gt;
body.action-view .product-summary-card {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
body.action-view .product-fullview {&lt;br /&gt;
    display: flex;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Main Page grid: show summary card (as product card), hide full layout */&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-fullview {&lt;br /&gt;
    display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit mode: show summary card with yellow cue */&lt;br /&gt;
body:not(.action-view) .product-summary-card {&lt;br /&gt;
    display: block;&lt;br /&gt;
    background: #fff8e1;&lt;br /&gt;
    border: 2px dashed #f0a830;&lt;br /&gt;
    padding: 14px;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    margin-bottom: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
body:not(.action-view) .product-summary-card::before {&lt;br /&gt;
    content: &amp;quot;📦 Main Page Card Preview — edit description in the template below&amp;quot;;&lt;br /&gt;
    display: block;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-products-grid .product-summary-card {&lt;br /&gt;
    background: transparent;&lt;br /&gt;
    border: none;&lt;br /&gt;
    padding: 0;&lt;br /&gt;
    margin: 0;&lt;br /&gt;
}&lt;br /&gt;
.main-page-products-grid .product-summary-card::before {&lt;br /&gt;
    content: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Products grid */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
/* =========================&lt;br /&gt;
   MAIN PAGE GRIDS&lt;br /&gt;
   ========================= */&lt;br /&gt;
.main-page-products-grid {&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-wrap: wrap;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 24px auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card {&lt;br /&gt;
    background: white;&lt;br /&gt;
    border: 1px solid #e0e0e0;&lt;br /&gt;
    border-radius: 8px;&lt;br /&gt;
    padding: 28px 20px 24px;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    transition: all 0.2s;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    flex-direction: column;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    flex: 0 0 280px;&lt;br /&gt;
    box-sizing: border-box;&lt;br /&gt;
    position: relative;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-card:hover {&lt;br /&gt;
    border-color: #2c5aa0;&lt;br /&gt;
    box-shadow: 0 6px 20px rgba(44, 90, 160, 0.12);&lt;br /&gt;
    transform: translateY(-2px);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Stretched link: link trong title cover toàn card */&lt;br /&gt;
.main-page-product-title a::after {&lt;br /&gt;
    content: &amp;quot;&amp;quot;;&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 0;&lt;br /&gt;
    left: 0;&lt;br /&gt;
    right: 0;&lt;br /&gt;
    bottom: 0;&lt;br /&gt;
    z-index: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Đảm bảo các phần khác hiển thị nhưng link cover phía trên */&lt;br /&gt;
.main-page-product-icon,&lt;br /&gt;
.main-page-product-title,&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    z-index: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Nếu có link khác trong card (vd icon có link riêng), giữ nó clickable trên cùng */&lt;br /&gt;
.main-page-product-card a:not(.main-page-product-title a) {&lt;br /&gt;
    position: relative;&lt;br /&gt;
    z-index: 2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-card:hover .main-page-product-title a {&lt;br /&gt;
    text-decoration: underline;&lt;br /&gt;
}&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon {&lt;br /&gt;
    width: 140px;&lt;br /&gt;
    height: 140px;&lt;br /&gt;
    display: flex;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    margin: 0 auto 16px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-icon img {&lt;br /&gt;
    max-width: 100%;&lt;br /&gt;
    max-height: 100%;&lt;br /&gt;
    object-fit: contain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title {&lt;br /&gt;
    font-size: 22px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin: 8px 0 14px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-product-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 14px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
    text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Categories grid - 4 cards bottom */&lt;br /&gt;
.main-page-categories-grid {&lt;br /&gt;
    display: grid;&lt;br /&gt;
    grid-template-columns: repeat(4, 1fr);&lt;br /&gt;
    gap: 24px;&lt;br /&gt;
    margin: 30px 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-card {&lt;br /&gt;
    text-align: center;&lt;br /&gt;
    padding: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-icon {&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    margin-bottom: 12px;&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title {&lt;br /&gt;
    font-size: 18px;&lt;br /&gt;
    font-weight: 700;&lt;br /&gt;
    margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-title a {&lt;br /&gt;
    color: #2c5aa0;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.main-page-category-desc {&lt;br /&gt;
    color: #444;&lt;br /&gt;
    font-size: 13px;&lt;br /&gt;
    line-height: 1.5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
/* Override all blue to SOJI brand color         */&lt;br /&gt;
/* ============================================ */&lt;br /&gt;
&lt;br /&gt;
/* Heading H2 */&lt;br /&gt;
.mw-parser-output h2 {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #eaecf0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Page title H1 */&lt;br /&gt;
.mw-page-title,&lt;br /&gt;
#firstHeading,&lt;br /&gt;
h1.firstHeading {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki links */&lt;br /&gt;
.mw-parser-output a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:visited {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.mw-parser-output a:hover {&lt;br /&gt;
    color: #003a7a;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Import font Google Fonts */&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Mulish:wght@600;700;800&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
/* Category block title — apply font mới */&lt;br /&gt;
.category-block-title,&lt;br /&gt;
.category-block-title a {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
    font-family: &#039;Mulish&#039;, -apple-system, &amp;quot;Segoe UI&amp;quot;, sans-serif !important;&lt;br /&gt;
    font-weight: 700 !important;&lt;br /&gt;
    letter-spacing: 0.3px !important;&lt;br /&gt;
    font-size: 1.15em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Category block hover border */&lt;br /&gt;
.category-block:hover {&lt;br /&gt;
    border-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Toggle text */&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;] {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span[class*=&amp;quot;mw-customtoggle-cb-&amp;quot;]:hover {&lt;br /&gt;
    color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Chevron arrow */&lt;br /&gt;
.toggle-arrow {&lt;br /&gt;
    border-right-color: #0054A6 !important;&lt;br /&gt;
    border-bottom-color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.category-block-toggle span:hover .toggle-arrow {&lt;br /&gt;
    border-color: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document download button */&lt;br /&gt;
.doc-download a {&lt;br /&gt;
    background: #0054A6 !important;&lt;br /&gt;
    color: #fff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.doc-download a:hover {&lt;br /&gt;
    background: #003a7a !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Document view link */&lt;br /&gt;
.doc-view a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Wiki link blue (mặc định Vector) */&lt;br /&gt;
a.external,&lt;br /&gt;
.mw-body-content a {&lt;br /&gt;
    color: #0054A6;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* TOC links */&lt;br /&gt;
.vector-toc a,&lt;br /&gt;
.vector-toc-link {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Sidebar menu links */&lt;br /&gt;
.vector-main-menu a,&lt;br /&gt;
#p-categorytree-portlet a,&lt;br /&gt;
.CategoryTreeLabel,&lt;br /&gt;
.CategoryTreeLabel a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Edit link bên cạnh heading */&lt;br /&gt;
.mw-parser-output h2 .mw-editsection a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Breadcrumb */&lt;br /&gt;
.custom-breadcrumb a {&lt;br /&gt;
    color: #0054A6 !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>