/* ==========================================================================
   CHỮ — Roboto, nhúng thẳng trong binary
   --------------------------------------------------------------------------
   Trước đây ba họ chữ (Be Vietnam Pro, Plus Jakarta Sans, JetBrains Mono) tải
   từ fonts.googleapis.com. Bỏ hẳn CDN vì ba lý do, xếp theo mức độ đau:

     1. Mỗi lượt xem trang là một lượt Google biết khách của trạm là ai. Không
        có lý do gì để đánh đổi thứ đó lấy 450KB.
     2. Trang phải chờ hai vòng DNS + TLS tới hai tên miền lạ trước khi có chữ.
     3. CDN chết hoặc bị chặn thì chữ tụt về font hệ thống, mà thang chữ ở
        dưới được đo theo Roboto.

   Chỉ lấy ba lát chữ dùng thật: vietnamese, latin-ext, latin. Bỏ cyrillic và
   greek — trang này không có chữ nào thuộc mấy bảng đó.

   Material Symbols cũng nhúng, và là bản CẮT theo tên icon (36 cái đang dùng)
   nên chỉ 5KB thay vì 4MB của bản đủ. Thêm icon mới thì phải tải lại font:
   sửa danh sách ICON trong scratchpad/font.py rồi chạy, đừng gọi thẳng CDN.
   ========================================================================== */
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-400-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-500-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-700-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 700;
  font-stretch: 100%;
  font-display: swap;
  src: url(/font/roboto-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/font/robotomono-400-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/font/robotomono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/font/robotomono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/font/robotomono-500-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/font/robotomono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/font/robotomono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/font/robotomono-700-vietnamese.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/font/robotomono-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Roboto Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/font/robotomono-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Material Symbols Outlined';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url(/font/msym.woff2) format('woff2');
}

/* ==========================================================================
   MATERIAL 3 — một bảng màu duy nhất, dựng từ tám màu thương hiệu
   --------------------------------------------------------------------------
   Không còn hệ chọn giao diện. Trước đây mỗi bộ tự khai một bảng trong khối
   body.theme-*; mười một bộ đó đã bỏ hẳn ngày 2026-09-08, bố cục của bộ "Kem
   & nắng" được nhấc lên thành luật trần vì đó là bộ đang chạy thật.

   Từ 2026-09-08 bảng không sinh từ một hạt giống nữa mà dựng từ TÁM màu
   thương hiệu Kendy chốt (khối NGUỒN ngay dưới). Phần còn thiếu — M3 cần
   chừng ba mươi vai màu — pha bằng cách kéo sáng/tối trên đúng trục màu của
   tám cái đó, không thêm sắc lạ.

   Hai luật cũ về --sang / --sang-muc giờ chính là cặp primary-container /
   primary của M3: --sang là mảng TÔ (lime nguyên bản), --sang-muc là dạng
   dùng làm CHỮ trên nền sáng (đã kéo tối cho đủ tương phản). Đừng đảo.

   Ba màu trạng thái (nhận / chờ / từ chối) KHÔNG sinh từ bảng này và không
   đổi theo bất cứ thứ gì: thợ nhìn quen màu, đổi là đọc nhầm đơn.

   Sinh lại bảng: scratchpad/m3.py — sửa mã màu gốc rồi chạy, nó in ra cả
   bảng tone lẫn tỉ số tương phản.
   ========================================================================== */
:root {
  /* Chặn hẳn chế độ tối của máy. Trước đây khách bật Dark Mode là cả site đổi
     sang tông navy/cyan: --sang thành #35C3EE, nền thành #071722 — hai màu
     không có trong bộ nhận diện. Tệ hơn, lớp --md-* KHÔNG đổi theo, nên thanh
     đáy vẫn kem sáng trong khi trang đã tối, và chip "Sửa cơ bản" thành chữ
     cyan trên nền cyan. Bảng màu của trạm không có tông tối; bịa ra một tông
     tối là bịa cả một bộ màu thứ hai chưa ai duyệt. Khoá sáng. */
  color-scheme: light;

  /* === NGUỒN — sửa tám dòng này là đổi màu CẢ SITE ========================
     Mọi tên màu bên dưới, cả --md-* lẫn tên cũ, đều trỏ về đây. Ba nghìn dòng
     CSS phía dưới không phải sửa một chữ. */
  --lime:    #FFC72C;   /* nhận diện — CHỈ trên nền tối (hero, chân trang, logo) */
  --forest:  #2E2A5E;   /* màu kỹ thuật: tấm tối, chữ đậm */
  --green:   #564D9B;   /* nhấn phụ: mảng, icon, chữ to */
  --kem:     #CDC9DE;   /* nền trang */
  --trang:   #F6F4FB;   /* mặt thẻ */
  --chu:     #181528;
  --chu-mo:  #4E496E;
  --duong:   #A5A0C0;   /* viền */

  /* === Pha ra từ tám màu trên =============================================
     M3 cần chừng ba mươi vai màu; Kendy cho tám. Số còn lại pha bằng cách kéo
     sáng/tối trên đúng trục màu của tám cái kia, không thêm sắc lạ nào.

     --green-dam là cái đáng nói nhất. Đo được: --green #564D9B trên nền kem
     chỉ 4.44:1, trượt chuẩn AA (4.5) của chữ thường — trượt sát nút vẫn là
     trượt, và người trên bốn mươi tuổi đọc dưới nắng là hỏng. Kéo tối xuống
     #3A3276 được 6.85:1. Nên: chữ và icon nhấn dùng --green-dam; --green chỉ
     cho mảng lớn và chữ to. Đừng đảo hai cái này.

     Tên biến giữ nguyên là CỐ Ý. Ba nghìn dòng dưới gọi --lime / --forest /
     --green; đổi tên là sửa mù cả nghìn chỗ để đổi đúng ba mã màu. Đọc tên
     theo VAI, đừng đọc theo nghĩa đen: --lime là màu nhấn (nay là vàng),
     --forest là tấm tối (nay là tím than), --green là nhấn phụ. */
  --lime-nhat:   #FFE194;
  --lime-dam:    #E19F0E;
  --green-dam:   #3A3276;
  --green-2:     #4A418B;
  --forest-2:    #423C7C;
  --kem-2:       #CDC9DE;
  --kem-3:       #B9B4CF;
  --kem-4:       #A9A4C1;
  --kem-5:       #9691B0;
  --tren-toi:    #EDEBF7;
  --tren-toi-mo: #B2ADCA;
  --duong-dam:   #6A638C;

  /* === Vai màu Material 3 ================================================ */
  --md-primary:                   var(--green-dam);
  --md-on-primary:                var(--trang);
  --md-primary-container:         var(--green-dam);
  --md-on-primary-container:      #FFFFFF;
  --md-secondary:                 var(--chu-mo);
  --md-on-secondary:              var(--trang);
  --md-secondary-container:       #E8E5F5;
  --md-on-secondary-container:    var(--forest);
  --md-tertiary:                  var(--green-dam);
  --md-on-tertiary:               var(--trang);
  --md-tertiary-container:        #FAEDC6;
  --md-on-tertiary-container:     var(--forest);
  --md-error:                     #BF0031;
  --md-on-error:                  #FFFFFF;
  --md-error-container:           #FFDAD8;
  --md-on-error-container:        #410004;

  --md-surface:                   var(--kem);
  --md-on-surface:                var(--chu);
  --md-surface-variant:           var(--kem-3);
  --md-on-surface-variant:        var(--chu-mo);
  --md-surface-container-lowest:  var(--trang);
  --md-surface-container-low:     #DFDCEC;
  --md-surface-container:         var(--kem-2);
  --md-surface-container-high:    var(--kem-3);
  --md-surface-container-highest: var(--kem-4);
  --md-surface-dim:               var(--kem-5);
  --md-inverse-surface:           var(--forest);
  --md-inverse-on-surface:        var(--tren-toi);
  --md-inverse-primary:           var(--lime);
  --md-outline:                   var(--duong-dam);
  --md-outline-variant:           var(--duong);
  --md-shadow:                    var(--forest);
  --md-scrim:                     var(--forest);

  /* Tấm tối: đầu trang, hero, chân trang. M3 không có token riêng cho "mảng
     tối trên giao diện sáng" nên dùng thẳng Forest và một nấc sáng hơn của
     nó — cùng trục màu với lime nên tấm tối vẫn đọc ra là của trạm, không
     phải một mảng xám vô danh. */
  --md-toi:            var(--forest);
  --md-toi-2:          var(--forest-2);
  --md-tren-toi:       var(--tren-toi);
  --md-tren-toi-mo:    var(--tren-toi-mo);

  /* Đổ bóng. Bản trước dùng đúng thang M3: rgba(0,0,0,.30) — đen thuần và
     nặng, trên nền kem nó ra vệt xám bẩn. Kendy chốt "không đổ bóng nặng".
     Ba nấc dưới đây nhẹ hơn hẳn và pha sắc Forest thay vì đen, nên bóng đổ
     xuống nền kem vẫn cùng họ màu chứ không xỉn đi. */
  --md-elev-1: 0 1px 2px rgba(46,42,94,.10), 0 1px 3px rgba(46,42,94,.07);
  --md-elev-2: 0 2px 4px rgba(46,42,94,.09), 0 4px 10px -2px rgba(46,42,94,.09);
  --md-elev-3: 0 4px 8px -2px rgba(46,42,94,.10), 0 12px 24px -8px rgba(46,42,94,.14);

  /* --- Tên cũ giữ nguyên, trỏ vào token M3 ---------------------------------
     Ba nghìn dòng CSS bên dưới gọi theo tên cũ. Đổi tên hết là sửa mù cả
     nghìn chỗ; trỏ lại thế này thì đổi màu chỉ ở một nơi mà không đụng gì
     phía dưới. Tên mới --md-* dùng cho linh kiện M3 viết từ đây trở đi. */
  --nen:        var(--md-surface);
  --nen-2:      var(--md-surface-container);
  --the:        var(--md-surface-container-lowest);
  --muc:        var(--md-on-surface);
  --muc-mo:     var(--md-on-surface-variant);
  --vien:       var(--md-outline-variant);
  --vien-dam:   var(--md-outline);

  --th:         var(--md-primary);
  --th-2:       var(--md-toi-2);
  --th-dam:     var(--md-toi);
  --th-nen:     var(--md-secondary-container);
  --th-vien:    var(--duong);

  --sang:          var(--md-primary-container);
  --sang-muc:      var(--md-primary);
  --sang-tren-toi: var(--md-inverse-primary);
  --tren-sang:     var(--md-on-primary-container);
  --tren-sang-toi: var(--forest);

  --tren-th:    var(--md-on-primary);
  --tren-dam:   var(--md-tren-toi);
  --tren-dam-mo:var(--md-tren-toi-mo);

  --nhan:       #1C6B57;   /* TRẠNG THÁI: nhận / đã giao */
  --nhan-nen:   #E2EFE9;
  --tuchoi:     #B23A22;   /* TRẠNG THÁI: từ chối */
  --tuchoi-nen: #FAE9E4;
  --cho:        #8A6512;   /* TRẠNG THÁI: đang chờ */
  --cho-nen:    #F8EEDA;

  --nhan-manh:  var(--md-on-surface);
  --bong:       var(--md-elev-1);
  --bong-cao:   var(--md-elev-3);

  /* Bo góc: KHÔNG đụng trong lần đổi màu này. Thang mới của Kendy
     (14/18/20/24) to hơn thang đang chạy, mà màn /app phải lọt đúng một màn
     hình — đổi bo góc cùng lúc với đổi màu thì lúc nhìn không biết cái nào
     gây ra cái gì. Để sang lượt Design System đầy đủ. */
  --r:          12px;
  --r-nho:      8px;
  --r-lon:      16px;

  /* Màu cho bản vẽ SVG. Tách riêng khỏi màu giao diện vì hình còn phải chạy
     trên tấm tối của hero, chỗ mà --muc và --vien đều sai. */
  --sv-net:  var(--chu-mo);
  --sv-mo:   #9E9AB7;
  --sv-to:   var(--kem-2);
  --sv-man:  var(--forest);
  --sv-nhan: var(--green-dam);
  --sv-ok:   #1C6B57;
  --sv-canh: #B23A22;
  /* Vật liệu trong sơ đồ cấu tạo. Bọt và vách đúc phải khác nhau bằng MÀU,
     không chỉ bằng hoa văn: in đen trắng hay nhìn nhanh trên điện thoại thì
     hai thứ hoa văn chấm giống nhau đọc ra cùng một vật liệu. */
  --sv-bot:     #8A6512;
  --sv-bot-nen: #F8EEDA;
  --sv-dac:     #6A638C;
}

/* Bảng màu VOLT cũ (trước 2026-09-10), giữ nguyên để đổi lại cho nhanh nếu
   bảng tím-vàng mới không hợp. Thêm data-mau="cu" vào thẻ <html> là về y như
   trước, không phải lục git. Đây KHÔNG phải bảng dự phòng đã duyệt — bảng dự
   phòng của bộ nhận diện mới là k8 xanh dầu + hổ phách, xem
   brand/10-chot-dau-hieu.md. */
:root[data-mau="cu"] {
  --lime:    #D3F02B;
  --forest:  #2D3400;
  --green:   #566500;
  --kem:     #FAFAF2;
  --trang:   #FFFFF9;
  --chu:     #1C1C16;
  --chu-mo:  #47483B;
  --duong:   #C7C8B8;

  --lime-nhat:   #F9FFAC;
  --lime-dam:    #B8D300;
  --green-dam:   #566500;
  --forest-2:    #404C00;
  --kem-2:       #EEEEE7;
  --kem-3:       #E8E9E1;
  --kem-4:       #E3E3DB;
  --kem-5:       #DADAD3;
  --tren-toi:    #E3E3DB;
  --tren-toi-mo: #C7C7BF;
  --duong-dam:   #77786A;

  --md-secondary:              #5E6046;
  --md-secondary-container:    #E3E5C6;
  --md-tertiary:               #2D6858;
  --md-tertiary-container:     #B1EFDB;
  --md-surface-container-low:  #F4F4EC;
  --md-elev-1: 0 1px 2px 0 rgba(0,0,0,.30), 0 1px 3px 1px rgba(0,0,0,.15);
  --md-elev-2: 0 1px 2px 0 rgba(0,0,0,.30), 0 2px 6px 2px rgba(0,0,0,.15);
  --md-elev-3: 0 1px 3px 0 rgba(0,0,0,.30), 0 4px 8px 3px rgba(0,0,0,.15);
  --sv-mo:   #A9AA9B;
}
* { box-sizing: border-box; }
/* Android/iOS vẽ sẵn một ô xám mờ chớp lên mỗi lần chạm vào link hay nút — nó
   là hình CHỮ NHẬT bao quanh thẻ, không theo bo góc của ô, nên đập vào mắt
   đúng như Kendy tả: "ấn vào icon thấy nháy cái mờ mờ hình vuông". Tắt hẳn.
   Không mất phản hồi chạm: mọi thứ bấm được ở đây đều đã có :active riêng
   (ô lún xuống, bóng co lại, nền đổi) — vừa đẹp hơn vừa đúng hình dạng thật. */
html { -webkit-tap-highlight-color: transparent; }
html { scroll-behavior: smooth; }
/* Nền giấy: một lớp nhiễu rất mỏng (3.5%) trải trên toàn trang. Không ai
   nhìn ra nó, nhưng bỏ đi thì các mảng màu lớn phẳng lì như ô tô màu. */
body {
  margin: 0;
  background-color: var(--nen);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.045'/%3E%3C/svg%3E");
  color: var(--muc);
  font: 400 16px/1.68 Roboto, system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  /* Chạm nhanh hai cái vào cùng một chỗ thì trình duyệt điện thoại hiểu là
     "phóng to đoạn này" và trang nhảy cỡ — khách bấm hụt một nút rồi bấm lại
     ngay là dính. manipulation bỏ đúng cử chỉ ấy; chụm hai ngón để phóng to
     vẫn còn, nên người mắt kém không mất gì. */
  touch-action: manipulation;
  /* Xoay ngang máy là iOS tự thổi chữ to lên nếu không chặn. */
  -webkit-text-size-adjust: 100%;
}
/* Thuộc tính hidden phải thắng mọi thứ. Trình duyệt cho nó display:none ở mức
   yếu nhất, nên bất kỳ luật nào của mình đặt display:flex hay display:grid
   cho chính phần tử ấy là hidden mất tác dụng — phần tử "đang ẩn" vẫn nằm
   chình ình. Bốn chỗ trong site này đã dính: thẻ mời cài app, khối hướng dẫn
   iPhone, danh sách tệp vừa chọn, thẻ đơn máy nhớ giùm. Đóng một lần ở đây
   thay vì vá từng chỗ, và chỗ nào viết sau này cũng khỏi dính. */
[hidden] { display: none !important; }

.khung { max-width: 1140px; margin: 0 auto; padding: 0 24px; }
.hep { max-width: 700px; }

/* Tiêu đề dùng chung một họ với thân bài. Trước đây tiêu đề là Plus Jakarta
   Sans còn thân bài là Be Vietnam Pro; Material 3 dựng cả thang chữ trên một
   họ duy nhất, phân biệt bằng nét và cỡ chứ không bằng đổi font. Giãn chữ âm
   ở cỡ lớn thì giữ — đó là luật của chính Roboto, không phải của bộ cũ. */
h1,
h2,
h3,
h4 {
  font-family: Roboto, system-ui, sans-serif;
  text-wrap: balance; margin: 0; line-height: 1.14;
  font-weight: 700;
}
h1 {
  font-size: clamp(32px, 4.8vw, 56px); letter-spacing: -.038em; line-height: 1.02;
  font-weight: 800;
}
h2 {
  font-size: clamp(23px, 2.9vw, 34px); letter-spacing: -.03em; line-height: 1.1;
  font-weight: 800;
}
h3 { font-size: 18.5px; letter-spacing: -.018em; font-weight: 700; }
h4 { font-size: 16px; letter-spacing: -.012em; font-weight: 700; }
p { margin: 0; }
a { color: var(--sang-muc); text-underline-offset: 2px; }

/* --- Bản vẽ SVG ---------------------------------------------------------- */
.sv { width: 100%; height: auto; display: block; overflow: visible; }
/* Nhãn trên bản vẽ. Cỡ chữ tính theo bề rộng viewBox chứ không theo pixel màn
   hình: hình rộng 520 đơn vị hiển thị trong cột ~410px, tức mọi thứ co lại còn
   ~0.79. Nhãn 10px từng đọc ra 8px trên màn — không đọc được. */
.sv-chu {
  font: 700 13px "Roboto Mono", ui-monospace, monospace;
  letter-spacing: .1em; fill: var(--sv-nhan);
}
.sv-chu-ok { fill: var(--sv-ok); }
.sv-chu-canh { fill: var(--sv-canh); }

/* Sơ đồ cấu tạo trong panel /qt/vot. Hình rộng 660 đơn vị: thả hết bề ngang
   thẻ thì nét mảnh đi và chữ nhãn nhỏ lại theo, nên kẹp bằng khổ bản vẽ. */
.ct-so-do { margin: 2px 0 6px; }
.ct-so-do .sv { max-width: 760px; margin: 0 auto; }
.ct-hoi { font-size: 42px; letter-spacing: 0; }

/* Chú giải: mỗi vật liệu một ô mẫu. Ô phải khác nhau bằng MÀU trước, hoa văn
   sau — nhìn nhanh trên điện thoại thì hai thứ chấm bi đọc ra một thứ. */
.ct-chu {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin: 2px 0 0; padding: 0; list-style: none;
}
.ct-chu li {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--muc-mo);
}
.ct-o {
  width: 18px; height: 13px; border-radius: 3px; flex: none;
  border: 1.5px solid var(--sv-net); background: var(--sv-to);
}
.ct-o-vo   { border-width: 3px; }
.ct-o-toong {
  background-image:
    repeating-linear-gradient(60deg,  var(--sv-net) 0 1px, transparent 1px 5px),
    repeating-linear-gradient(-60deg, var(--sv-net) 0 1px, transparent 1px 5px);
}
.ct-o-keo  { background: var(--sv-canh); border-color: var(--sv-canh); height: 7px; }
.ct-o-vien { background: none; border: 3px solid var(--sv-net); opacity: .55; }
.ct-o-bot {
  background: var(--sv-bot-nen); border-color: var(--sv-bot);
  background-image: radial-gradient(var(--sv-bot) 1.4px, transparent 1.5px);
  background-size: 6px 6px;
}
.ct-o-bot-thua {
  background: var(--sv-bot-nen); border-color: var(--sv-bot); border-style: dashed;
  background-image: radial-gradient(var(--sv-bot) 1.1px, transparent 1.2px);
  background-size: 9px 9px;
}
.ct-o-dac  { background: var(--sv-dac); border-color: var(--sv-dac); }
.ct-o-canh { background: var(--tuchoi-nen); border-color: var(--sv-canh); border-style: dashed; }
.ct-o-rong { background: none; border-style: dashed; }
.sv-so {
  font: 700 17px "Roboto Mono", ui-monospace, monospace;
  fill: var(--sv-nhan); letter-spacing: .04em;
}
/* Biểu tượng dịch vụ: nét mảnh, không tô, thừa hưởng màu chữ chỗ đặt nó. */
.bt {
  width: 29px; height: 29px; flex: none; display: block;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Biểu tượng màu, chỉ dùng trong vỏ app. Tự mang nền và màu trong hình nên
   không thừa hưởng currentColor như .bt — và vì thế cũng không dùng chung
   luật cỡ với .bt được, phải khai riêng ở mọi chỗ đặt nó. */
.btm { width: 30px; height: 30px; flex: none; display: block; }

/* Biến thể tô đặc của .bt. Dành cho hình quá nhỏ để đọc bằng nét. */
.bt-dac { fill: currentColor; stroke: none; }

.nhan-nho {
  font: 700 11px/1 "Roboto Mono", ui-monospace, monospace;
  letter-spacing: .16em; text-transform: uppercase; color: var(--sang-muc);
}
/* Nhãn mục có vạch dẫn: chia trang bằng đường kẻ, không bằng khoảng trống.
   Vạch chuyển dần sang trong suốt để không cắt ngang trang bằng một đường cứng. */
.nhan-vach { display: flex; align-items: center; gap: 12px; }
.nhan-vach::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--th-vien), transparent);
}
.so { font-family: "Roboto Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; }
/* Chữ trong dấu ` của markdown ra <code>. Cho nó giống .so để mã đơn gõ trong
   ô nội dung nhìn y như mã đơn viết thẳng trong template. */
code { font-family: "Roboto Mono", ui-monospace, monospace; font-variant-numeric: tabular-nums; font-size: .95em; }
.mo { color: var(--muc-mo); }
.nho { font-size: 13px; }
.doc { display: grid; gap: 14px; }
.doc-lon { display: grid; gap: 30px; }
.dan-lon { font-size: clamp(16.5px, 1.9vw, 19px); line-height: 1.6; color: var(--muc-mo); max-width: 58ch; }

/* --- Đầu trang: dải navy chạy hết chiều ngang ---------------------------- */
header.dau {
  background: color-mix(in srgb, var(--th-dam) 88%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid rgba(255,255,255,.08);
  position: sticky; top: 0; z-index: 20;
}
.dau-trong { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 11px 0; }
.logo {
  font-family: Roboto, system-ui, sans-serif; font-weight: 800; font-size: 20px;
  letter-spacing: -.01em; text-transform: none;
  color: var(--tren-th); text-decoration: none; display: flex; align-items: center; gap: 10px;
}
/* Cụm chữ bên phải phải NẰM CHUNG một hộp, không đứng thành hai ô flex rời.
   Khối logo giờ cao 59px (hình 44 + chữ T-PIC 12), mà align-items:baseline
   thì "Trạm Pickle" và dòng nghề bám lên mép trên của khối ấy — nhìn ra như
   chữ bị treo. Gói lại rồi canh giữa cả cụm; bên trong cụm vẫn baseline để
   tên 20px và dòng nghề 12.5px đứng chung một đường chân chữ. */
.logo-chu { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
/* Dấu hiệu Trạm Pickle (chốt 2026-09-10, xem brand/10-chot-dau-hieu.md):
   cây vợt pickleball thon nghiêng 18°, mặt vợt tách đôi hai màu theo đường
   nứt, một miếng băng dán nằm trên đường tách, quả bóng ở góc dưới phải.
   Nghĩa: *vá lại cho lành*.

   Hình sinh ở brand/nguon/_dung_web.py rồi ghi đè logo.html / logo4d.html —
   sửa hình thì sửa bên đó rồi chạy lại, đừng gõ tay vào tệp template.

   Hai màu đặt bằng biến vì hình nhúng thẳng vào HTML:
     --lg-chinh  thân vợt, cán, nửa dưới mặt vợt
     --lg-nhan   nửa trên mặt vợt, dải quấn cán, quả bóng
   Nền tối (dải đầu trang) → giấy + vàng.
   Nền sáng (thẻ mời cài app, thân app) → mực + vàng.

   Miếng băng dán #E0563B nằm cứng trong hình, KHÔNG có biến: nó là màu thứ
   ba cố định của bộ nhận diện, đổi theo giao diện là mất nghĩa miếng vá.

   Không có chữ trong hình — tên thương hiệu do .logo-ten in ra bằng chữ
   thật bên cạnh. Chỉ đặt height, width auto.

   KHUNG ĐÃ CẮT SÁT MỰC (2026-09-10): viewBox là "25.4 3.6 61.7 85.5", KHÔNG
   còn vuông (tỉ lệ 0.72). Khung vẽ 96×96 bỏ trống 11% chiều cao và 36% chiều
   ngang, nên height:44px cũ chỉ ra cây vợt cao 39px — đó là cái "logo hơi bé".
   Cắt xong, height:46px cho mực cao đúng 46px (+18%) mà đầu trang chỉ cao
   thêm 4px. HỆ QUẢ: chỗ nào ép aspect-ratio:1 hay đặt CẢ width lẫn height là
   kéo méo hình. Chỉ đặt height, để width:auto. */
/* Logo tải lên là ảnh ngoài: CSS không với vào đổi màu bên trong nó, và
   tệp nào cũng có thể rất rộng. Kẹp bề ngang để đầu trang không vỡ. */
img.logo-dau { max-width: 240px; object-fit: contain; }
.logo-dau {
  height: 46px; width: auto; flex: none; align-self: center;
  --lg-chinh: var(--trang); --lg-nhan: var(--lime);
}
/* Thẻ mời cài app nằm trên nền thẻ SÁNG, không phải dải đầu trang tối: bản
   trắng ở trên sẽ biến mất sạch. Trả về mực + volt. */
.moi-anh .logo-dau { --lg-chinh: var(--muc); --lg-nhan: var(--lime); }
.moi-anh .chu-tpic { --tp-chu: var(--muc); --tp-gach: var(--muc); }
/* Bản dùng ở đầu trang khách (logo4d.html) là CÙNG một hình, chỉ khác tên
   biến để hai bản đứng cạnh nhau trong một trang không giẫm màu nhau. */
/* width:auto la BAT BUOC: the <svg> mang san thuoc tinh width/height cua
   khung da cat (61.7 x 85.5), chi dat height trong CSS thi hop van rong
   61.7px — hinh nam giua va de lai khoang trong moi ben, nhin ra nhu logo bi
   day lech khoi ten. */
.logo-4d {
  --l4-chinh: var(--trang); --l4-nhan: var(--lime);
  width: auto; flex: none; align-self: center;
}
.logo .logo-4d { height: 46px; }
/* Khối xếp dọc: dấu hiệu ở trên, chữ T-PIC ở dưới (chốt 2026-09-10).
   Bản NGANG đã bị loại ở đầu trang — cạnh nó là "Trạm Pickle" viết bằng chữ
   thật, hai cụm chữ đứng cạnh nhau ăn gần nửa bề ngang màn hình cầm tay để
   nói đúng một cái tên. Xếp dọc thì chữ nằm dưới hình, bề ngang gần như không
   đổi, đầu trang chỉ cao thêm ~15px.

   Hai thẻ SVG rời trong một hộp flex-column, KHÔNG gộp thành một SVG: gộp lại
   thì bề ngang do chữ quyết định, hình vợt tự co theo, và hết đường đặt riêng
   cỡ từng phần cho đầu trang / app / khổ hẹp.

   Chữ cao 13px trong khi hình cao 46px: chữ rộng gấp 4.32 lần chiều cao chữ
   (147:34 trong hệ 96 của dấu hiệu), nên 13px chữ đã rộng 56px — rộng hơn cả
   hình. Cho cao hơn nữa là khối chữ nặng hơn khối hình. */
.logo-khoi {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  flex: none; align-self: center;
}
/* Gạch nối là MỐI NỐI — nghề sửa chữa nằm ở đó. Nền TỐI thì nó màu vàng (luật
   Một Chấm: màu nhấn xuất hiện đúng một lần trong bố cục). Nền SÁNG thì phải
   vẽ CÙNG MÀU CHỮ: vàng trên nền giấy chỉ được 1.6:1, mà miếng gạch chỉ rộng
   4 đơn vị nên nó không "mờ đi" mà biến mất hẳn. */
.chu-tpic {
  height: 13px; width: auto; display: block; flex: none;
  --tp-chu: var(--trang); --tp-gach: var(--lime);
}
/* Vạch ngăn giữa chữ trong logo và tên tiếng Việt: hai cụm chữ đứng sát nhau
   thì đọc thành một cụm dài. */
.logo-ten { padding-left: 12px; border-left: 2px solid rgba(255,255,255,.22); }
.logo-phu {
  font-family: Roboto, sans-serif; font-size: 12.5px; color: var(--tren-dam-mo);
  font-weight: 400; font-stretch: 100%; letter-spacing: 0; text-transform: none;
}
.dau-trong nav { margin-left: auto; display: flex; gap: 2px; flex-wrap: wrap; align-items: center; }
.dau-trong nav a {
  color: var(--tren-dam); text-decoration: none; font-size: 14.5px; font-weight: 500;
  padding: 7px 11px; border-radius: var(--r-nho);
}
.dau-trong nav a:hover { color: #fff; background: rgba(255,255,255,.09); }
/* Mục đang mở: gạch chân màu nhấn, không tô nền — nền tối tô mảng là nặng mặt. */
.dau-trong nav a.day {
  color: #fff; font-weight: 600; background: transparent;
  box-shadow: inset 0 -2px 0 var(--sang-tren-toi); border-radius: 0;
}
.nut-nho,
.dau-trong nav a.nut-nho {
  display: inline-block; padding: 8px 17px; border-radius: 999px;
  background: var(--sang); color: var(--tren-sang); font-weight: 700;
  box-shadow: none;
}
/* Cùng luật với .nut-chinh:hover. Mã cyan trước đây ở đây là một màu thứ năm
   không có trong logo. */
.nut-nho:hover,
.dau-trong nav a.nut-nho:hover {
  background: color-mix(in srgb, var(--sang) 86%, var(--muc)); color: var(--tren-sang);
}
/* Nút "Tra cứu" nằm trong thanh đầu trang, tức trên navy. Luật chung phía
   trên tô ô-liu — đúng cho bảng quản lý nền kem, nhưng ô-liu trên navy chỉ
   hơn nhau 2.1:1, nút biến mất. Trên nền tối thì lime. */
.dau-trong nav a.nut-nho,
.dau-trong nav a.nut-nho:hover {
  background: var(--sang-tren-toi); color: var(--tren-sang-toi);
}
/* Nút "Thoát" ở đầu trang quản trị nằm trên nền navy — nút phụ mặc định là
   chữ mực trên nền trong suốt, ở đây sẽ chìm hẳn. Đảo sang tông sáng. */
.dau-trong button.phu {
  background: transparent; color: var(--tren-dam);
  border: 1px solid rgba(255,255,255,.28);
}
.dau-trong button.phu:hover { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.5); }

/* --- Khối ---------------------------------------------------------------- */
section { padding: 60px 0; }
section + section { border-top: 1px solid var(--vien); }
section.nen2 { background: var(--nen-2); }

.the {
  background: var(--the); border: 1px solid var(--vien);
  border-radius: var(--r); padding: 22px;
}

/* --- Hero: TẤM, không phải DẢI --------------------------------------------
   Trước đây hero là một băng navy chạy hết chiều ngang màn hình. Trên màn
   rộng nó thành một mảng xanh 1600px không có gì bên trong — nặng và trống
   cùng lúc. Giờ bó lại thành một tấm bo góc nằm trong khung nội dung: cùng
   màu ấy nhưng chiếm chưa tới hai phần ba bề ngang, và có mép để mắt bám. */
.hero {
  padding: 24px 0 0;
  background: none;
  border-top: none;
}
.hero > .khung {
  position: relative; overflow: hidden;
  padding: 56px 46px 52px;
  border-radius: var(--r-lon);
  background: linear-gradient(158deg, var(--th) 0%, var(--th-dam) 92%);
  color: var(--tren-dam);
  box-shadow: var(--bong-cao);
}
@media (max-width: 680px) {
  .hero { padding-top: 14px; }
  .hero > .khung { padding: 36px 22px 34px; border-radius: 14px; }
}
.hero > .khung::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(760px 340px at 88% -22%, color-mix(in srgb, var(--sang-tren-toi) 32%, transparent), transparent 62%),
    radial-gradient(520px 280px at 2% 118%, color-mix(in srgb, var(--sang-tren-toi) 14%, transparent), transparent 66%);
}
/* Lưới kỹ thuật rất mờ phủ lên tấm hero — đủ để mặt phẳng có kết cấu, không
   đủ để ai kịp nhận ra là ô vuông. */
.hero > .khung::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(120% 100% at 70% 0%, #000 10%, transparent 72%);
  -webkit-mask-image: radial-gradient(120% 100% at 70% 0%, #000 10%, transparent 72%);
}
.hero > .khung > * { position: relative; z-index: 1; }
.hero h1,
.hero h2,
.hero h3,
.hero h4 { color: #fff; }
.hero h1 { max-width: 17ch; margin-top: 18px; }
.hero .dan,
.hero > .khung > .dan { font-size: clamp(16.5px, 2vw, 19px); color: var(--tren-dam-mo); max-width: 54ch; margin-top: 20px; line-height: 1.6; }
.hero .dan-lon,
.hero > .khung > p,
.hero > .khung > .nho,
.hero > .khung > .mo { color: var(--tren-dam-mo); }
/* Nhãn mono trên tấm hero tối. Với volt của T-PIC thì --sang tự đủ sáng, nhưng
   giao diện lấy màu nhấn là xanh cobalt hay đỏ thì --sang trên nền tối chỉ còn
   3-4:1 — đọc không nổi ở cỡ 12px. Những bộ đó khai thêm --sang-tren-toi (bản
   nâng sáng trên đúng trục của chính màu nhấn, tới đúng 4.5:1); bộ nào không
   khai thì rơi về --sang như cũ. */
.hero .nhan-nho { color: var(--sang-tren-toi, var(--sang)); }
/* Dòng nhãn hero là câu duy nhất nói trạm LÀM GÌ — 11px chữ mảnh trên nền
   tối thì mắt lướt qua mất. Phóng lên và bọc một khung mỏng: vẫn là nhãn nhỏ,
   nhưng thành một vật thể có mép chứ không phải vệt chữ nhạt. */
.hero-lon .nhan-nho {
  display: inline-flex; align-items: center;
  padding: 7px 13px; border-radius: 999px;
  font-size: 12.5px; letter-spacing: .13em;
  color: var(--sang-tren-toi, var(--sang));
  background: color-mix(in srgb, var(--sang-tren-toi) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--sang-tren-toi) 34%, transparent);
}
.hero .nhan-vach::after { background: linear-gradient(90deg, rgba(255,255,255,.24), transparent); }
.hero a { color: var(--sang-tren-toi); }
.hero .so { color: #fff; }
.hero .the .so,
.hero .phieu .so,
.hero .bao .so { color: var(--muc); }
.hero-nut { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 30px; }
/* Dòng địa chỉ dưới hàng nút. Ghim vẽ bằng SVG nhúng chứ không phải emoji:
   emoji ghim trên Windows ra màu đỏ tươi, đặt cạnh chữ trắng trên nền tối
   trông như báo lỗi. */
/* Trang Về chúng tôi -------------------------------------------------- */
.tram-o {
  margin: 18px 0 0; font-size: clamp(22px, 2.6vw, 30px);
  font-weight: 600; line-height: 1.25;
}
.tram-gio { margin: 8px 0 0; color: var(--muc-mo); }
.tram-gio span { color: var(--muc); font-weight: 600; }
/* Lưới chứ không phải băng chạy: ảnh chỗ làm việc là thứ khách soi kỹ, băng
   chạy bắt chờ tấm sau hiện lên thì soi kiểu gì. */
.tram-anh {
  display: grid; gap: 16px; margin-top: 22px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.tram-anh figure { margin: 0; }
.tram-anh img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
  border-radius: 14px; display: block;
}
.tram-anh figcaption { margin-top: 8px; font-size: 13.5px; color: var(--muc-mo); line-height: 1.45; }

.hero-lien-he {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px 22px; margin: 18px 0 0; font-size: 15px; line-height: 1.45;
  color: var(--tren-dam);
}
.hero-lien-he > * { display: inline-flex; align-items: center; gap: 9px; }
/* Số điện thoại phải trông bấm được: trên nền tối một chữ trắng trơn không ai
   biết đó là nút gọi. Gạch chân mờ, đậm lên khi rê chuột. */
.hero-lien-he a {
  color: #fff; text-decoration: underline;
  text-decoration-color: rgba(255,255,255,.32);
  text-underline-offset: 4px;
}
.hero-lien-he a:hover { text-decoration-color: #fff; }
.hero-lien-he svg {
  flex: none; width: 17px; height: 17px;
  fill: none; stroke: var(--sang-tren-toi, var(--sang));
  stroke-width: 1.7; stroke-linejoin: round;
}

/* Thẻ trắng đặt trên nền hero phải lấy lại màu chữ của nền sáng. */
.hero .the,
.hero .phieu,
.hero .bao,
.hero .the-nhom { color: var(--muc); }
.hero .the h1,
.hero .the h2,
.hero .the h3,
.hero .the h4 { color: var(--muc); }
.hero .the .mo,
.hero .the .nho,
.hero .the p.mo { color: var(--muc-mo); }
.hero .the a { color: var(--sang-muc); }
.hero .bao-ok { color: var(--nhan); }
.hero .bao-loi { color: var(--tuchoi); }
.hero .bao-luu { color: var(--cho); }
/* Chip trong hero: nền tối nên chip xám nhạt bị chìm, đổi sang kính mờ. */
.hero .chip-trung { background: rgba(255,255,255,.12); color: var(--tren-dam); border-color: rgba(255,255,255,.2); }
/* Bản vẽ đặt trên tấm navy: đảo cả bộ màu SVG sang tông sáng. */
.hero .sv {
  --sv-net:  rgba(226,222,247,.86);
  --sv-mo:   rgba(162,156,201,.62);
  --sv-to:   rgba(255,255,255,.055);
  --sv-man:  #0E0B1E;
  --sv-nhan: var(--sang-tren-toi);
}

.nut {
  display: inline-block; padding: 13px 26px; border-radius: 999px; text-decoration: none;
  font-weight: 700; font-size: 15px; border: 1px solid transparent;
}
.nut-chinh { background: var(--sang); color: var(--tren-sang); }
/* Hover của nút màu nhấn: cùng màu, ĐẬM hơn — pha thêm 14% màu mực. Trước
   đây pha thêm trắng, nhưng trên nền trang trắng thì hover làm nút nhạt đi,
   tức là mờ dần vào nền. Với vàng của T-PIC, 86% vàng + 14% mực ra ~#DFAE2B,
   đúng một bậc L thấp hơn trên trục vàng. Bản nền tối đảo lại ở body.toi. */
.nut-chinh:hover { background: color-mix(in srgb, var(--sang) 86%, var(--muc)); }
.nut-vien { border-color: var(--vien-dam); color: var(--muc); background: transparent; }
.nut-vien:hover { border-color: var(--th); color: var(--th); }
/* Nút viền đặt trên nền navy: viền và chữ phải sáng lên. */
.hero .nut-vien { border-color: rgba(255,255,255,.38); color: #fff; }
.hero .nut-vien:hover { border-color: #fff; background: rgba(255,255,255,.1); color: #fff; }
.hero .the .nut-vien { border-color: var(--vien-dam); color: var(--muc); }
.hero .the .nut-vien:hover { border-color: var(--th); color: var(--th); }
/* Nút gọi hành động của hero nằm trên tấm navy — ở đó lime mới là màu đọc
   được (10.3:1 trên forest), ô-liu sẽ chìm. Đây là chỗ luật tách vai hiện
   ra rõ nhất: cùng một lớp .nut-chinh, hai nền, hai màu. */
.hero .nut-chinh { background: var(--sang-tren-toi); color: var(--tren-sang-toi); }

/* Hero lệch: chữ bên trái, phiếu cân neo bên phải. */
.hero-doi { display: grid; gap: 40px; align-items: center; }
@media (min-width: 940px) { .hero-doi { grid-template-columns: minmax(0, 1.12fr) 348px; gap: 56px; } }

/* --- Phiếu cân -----------------------------------------------------------
   Vật đặc trưng nhất của nghề này. Cả trang chỉ có một cam kết kiểm chứng
   được bằng cái cân nhà bếp, nên nó đáng được vẽ ra chứ không chỉ kể lại. */
.phieu {
  background: var(--the); border: 1px solid var(--vien);
  border-radius: var(--r); overflow: hidden; box-shadow: var(--bong-cao);
}
.phieu .dinh {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 13px 16px; background: var(--th-dam); color: var(--tren-dam);
  font: 700 11px/1.4 "Roboto Mono", monospace; letter-spacing: .14em; text-transform: uppercase;
  border-bottom: 2px solid var(--sang-tren-toi);
}
.phieu .dinh span { letter-spacing: .06em; color: var(--tren-dam-mo); font-weight: 500; }
.phieu .d {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 13px 16px; border-bottom: 1px solid var(--vien); font-size: 14px; color: var(--muc-mo);
}
.phieu .d b { font: 700 17px/1 "Roboto Mono", monospace; font-variant-numeric: tabular-nums; color: var(--muc); }
.phieu .chot {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 13px 16px; background: var(--nhan-nen); color: var(--nhan);
  font-size: 13.5px; font-weight: 600;
}
.phieu .chot b { font: 700 17px/1 "Roboto Mono", monospace; font-variant-numeric: tabular-nums; }
.phieu-ghi { margin-top: 11px; font-size: 12.5px; color: var(--tren-dam-mo); line-height: 1.5; }
.hero .phieu-ghi { color: var(--tren-dam-mo); }

/* --- Dải số: tấm biển thông số, không phải trang trí ---------------------
   Trước là một băng navy thứ hai nối ngay dưới hero — hai mảng xanh chồng
   nhau thành 600px xanh liên tục ở đầu trang. Giờ là ba ô sáng, và kéo lên
   đè một góc lên mép dưới tấm hero: hết cảnh các khối xếp thẳng hàng nhau. */
.bang-so { background: none; color: var(--muc); padding: 0; }
.bang-so > .khung { margin-top: -26px; position: relative; z-index: 3; }
@media (max-width: 680px) { .bang-so > .khung { margin-top: -18px; } }
.hero + .bang-so,
.hero + section,
.bang-so + section { border-top: none; }
.bang-so + section { padding-top: 58px; }
.bang-so-luoi {
  display: grid; gap: 1px; background: var(--vien);
  border: 1px solid var(--vien); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--bong-cao);
}
@media (min-width: 700px) { .bang-so-luoi { grid-template-columns: repeat(3, 1fr); } }
.bang-so-luoi > div { background: var(--the); padding: 22px 26px; }
.bang-so .v {
  font: 700 clamp(26px, 3.6vw, 36px)/1 "Roboto Mono", monospace;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; display: block;
  color: var(--th);
}
.bang-so .t { display: block; margin-top: 9px; font-size: 13.5px; color: var(--muc-mo); line-height: 1.5; }
.bang-so .n {
  font: 700 10.5px/1 "Roboto Mono", monospace; letter-spacing: .16em;
  text-transform: uppercase; color: var(--sang-muc); display: block; margin-bottom: 14px;
}

/* --- Lưới thẻ dịch vụ ---------------------------------------------------- */
.luoi { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
/* Lưới vạch: các ô dính liền, chia bằng đường kẻ 1px. Kỷ luật lưới thay cho
   thẻ nổi — ít đổ bóng, đọc ra một khối chứ không phải mấy mảnh rời. */
/* Lưới thẻ dịch vụ.

   Từng dùng flex-wrap cho hàng cuối tự giãn lấp chỗ trống. Hỏng: 5 thẻ ra
   4 + 1, và cái thứ 5 kéo dài hết 1140px trông như một lỗi layout.

   Đường kẻ 1px là nền --vien lòi qua khe gap. Từng thử vẽ bằng box-shadow của
   mỗi ô, nhưng nền của ô kế bên tô đè lên bóng của ô trước nên kẻ mất hẳn.
   Cách gap chỉ hỏng khi hàng cuối còn ô trống — mọi trang dùng lưới này đều
   dựng đủ 6 ô nên 1 / 2 / 3 cột đều chia hết hàng. */
.luoi-vach {
  display: grid; grid-template-columns: 1fr; gap: 1px;
  background: var(--vien);
  border: 1px solid var(--vien); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--bong);
}
/* Số cột cố định chứ không auto-fill. Auto-fill cho 4 cột ở 1140px, thành
   4 + 2 và để lộ hai ô trống thành một mảng xám. */
@media (min-width: 620px)  { .luoi-vach { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .luoi-vach { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.luoi-vach > * { background: var(--the); min-width: 0; }
.dv-the {
  background: var(--the); border: 1px solid var(--vien); border-radius: var(--r);
  padding: 20px; display: flex; flex-direction: column; gap: 9px;
  text-decoration: none; color: inherit; position: relative;
}
/* Vạch cyan chạy dọc mép trái khi rê chuột: dấu "đang chọn cái này". */
.dv-the::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--sang); opacity: 0;
}
.dv-the:hover::before { opacity: 1; }
.luoi-vach .dv-the { border: none; border-radius: 0; }
.dv-the:hover { border-color: var(--th-vien); box-shadow: var(--bong); }
/* Trong lưới thì ô không có viền riêng, nên hover chỉ đổi nền — bóng đổ ở đây
   sẽ tràn qua khe gap và nuốt mất đường kẻ. */
.luoi-vach .dv-the:hover { background: var(--th-nen); box-shadow: none; }

/* --- Danh sách việc khác, cột phải trang /dich-vu/<MA> -------------------
   Không dùng .dv-the ở đây. Cột phải rộng 340px, mà mỗi thẻ dịch vụ cao
   150px — bảy việc thành một cột dài 1000px chạy quá cả bài. Bản dọc chỉ giữ
   ba thứ: hình 30px để nhận ra việc, tên, và giá. Cùng một khối viền như
   .luoi-vach, chia bằng khe gap 1px lộ nền --vien. */
.dv-doc {
  display: grid; gap: 1px; background: var(--vien);
  border: 1px solid var(--vien); border-radius: var(--r); overflow: hidden;
}
.dv-doc > .nhan-nho {
  background: var(--the); padding: 14px 16px 12px; margin: 0;
}
.dv-doc > a {
  background: var(--the); padding: 12px 16px; text-decoration: none; color: inherit;
  display: grid; grid-template-columns: 30px minmax(0, 1fr); gap: 4px 12px;
  align-items: center;
}
.dv-doc > a:hover { background: var(--th-nen); }
.dv-doc .bt-o {
  width: 30px; height: 30px; border-radius: 8px; grid-row: span 2;
  background: var(--th-nen); color: var(--th);
  display: grid; place-items: center; border: 1px solid var(--th-vien);
}
.dv-doc > a:hover .bt-o { background: var(--sang); color: var(--tren-sang); border-color: var(--sang); }
.dv-doc .bt-o svg { width: 18px; height: 18px; }
.dv-doc .ten { font-weight: 600; font-size: 14.5px; line-height: 1.35; }
.dv-doc .gia { font-size: 12.5px; color: var(--muc-mo); line-height: 1.3; }
/* Hai ô cuối không phải việc: chữ bên phải là lời mời chứ không phải giá, nên
   bỏ cỡ chữ tiền đi cho khỏi đọc nhầm thành một con số. */
.dv-doc > a.het .ten { font-weight: 500; color: var(--muc-mo); }
.dv-doc > a.het .gia { color: var(--sang-muc); }

/* Việc nổi bật. Tô TẠI CHỖ trong lưới, không nhấc lên đầu — xem trangchu.html.
   Trong .luoi-vach ô không có viền riêng (đường kẻ là khe gap lộ nền ra), nên
   dấu hiệu phải nằm BÊN TRONG ô: một vành inset và cái vạch trái vốn chỉ hiện
   lúc rê chuột thì nay sáng thường trực.
   Vành dùng box-shadow inset chứ không dùng border: border làm ô dày thêm 2px
   và cả hàng lưới cao lên theo, ô nổi bật kéo lệch mấy ô bên cạnh. */
.dv-noi-bat::before { opacity: 1; width: 4px; }
.luoi-vach .dv-noi-bat,
.luoi-vach .dv-noi-bat:hover { box-shadow: inset 0 0 0 2px var(--sang); }
/* Ô biểu tượng KHÔNG đổi màu theo trạng thái nổi bật nữa: từ khi lưới web
   dùng chung bộ hình màu với app, hình đã tự mang nền riêng của nó. */

.dv-the .dau-the { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
/* Ô biểu tượng: mỗi dịch vụ có một hình riêng. Chín thẻ chữ giống hệt nhau
   là chín thẻ không ai đọc — cái hình cho mắt chỗ phân biệt trước khi đọc. */
.dv-the .bt-o {
  width: 50px; height: 50px; border-radius: 12px; margin-bottom: 3px;
  background: var(--th-nen); color: var(--th);
  display: grid; place-items: center;
  border: 1px solid var(--th-vien);
}
.dv-the:hover .bt-o { background: var(--sang); color: var(--tren-sang); border-color: var(--sang); }
/* Thẻ là flex column: chip không chặn align-self sẽ bị kéo rộng hết thẻ và
   trông như một ô input rỗng. */
.dv-the .chip { align-self: flex-start; }
.dv-the .p { font: 700 17px/1 "Roboto Mono", monospace; white-space: nowrap; color: var(--th); }
.dv-the .mota { font-size: 14px; color: var(--muc-mo); line-height: 1.55; }
.dv-the .chan { margin-top: auto; padding-top: 10px; font-size: 12.5px; color: var(--muc-mo); display: flex; gap: 16px; flex-wrap: wrap; }

/* --- Giá trên ô việc ------------------------------------------------------
   Khách quét lưới là quét con số trước, đọc chữ sau. Mono và tabular-nums để
   các ô xếp thẳng cột số với nhau; màu --th (không phải --muc-mo) vì đây là
   thứ người ta vào trang để tìm, không phải chú thích.

   Dùng lại đúng dáng của .dv-the .p vốn có sẵn cho chỗ này, chỉ nhỏ hơn một
   nấc: khoảng giá dài gấp đôi một con số, 17px là tràn sang dòng thứ hai
   trên máy hẹp. */
.dv-the .dv-gia {
  font: 700 16px/1.3 "Roboto Mono", ui-monospace, monospace;
  color: var(--th); font-variant-numeric: tabular-nums;
}
/* Câu chú thích dưới lưới: nói về CÁCH trạm báo giá, không thuộc ô nào, nên
   nằm ngoài lưới chứ không nhét vào từng thẻ. */
.dv-luoi-chu {
  margin: 18px 2px 0; max-width: 62ch;
  font-size: 13.5px; line-height: 1.6; color: var(--muc-mo);
}
/* Bản trang từng dịch vụ: cùng con số ấy, to hơn vì ở đây nó là nhân vật
   chính chứ không phải một ô trong lưới tám ô. */
/* Cỡ chữ theo bề ngang chứ không cố định 22px: "từ 100.000 đến 180.000đ" là
   23 ký tự mono, ở 22px nó dài 300px — trên máy 360 thì chạm mép thẻ hero. */
.dv-mot-gia {
  margin-top: 14px;
  font: 700 clamp(15px, 4.6vw, 22px)/1.25 "Roboto Mono", ui-monospace, monospace;
  color: var(--th); font-variant-numeric: tabular-nums;
}
/* Trong hero thì nền là chính màu --th, chữ cùng màu nền là chữ tàng hình. */
.hero .dv-mot-gia { color: var(--tren-dam); }

/* --- Bảng ---------------------------------------------------------------- */
.bang { width: 100%; border-collapse: collapse; font-size: 15px; }
.bang th {
  text-align: left; padding: 11px 12px; background: var(--th-nen);
  border-bottom: 1px solid var(--th-vien);
  font: 700 10.5px/1 "Roboto Mono", monospace; letter-spacing: .13em;
  text-transform: uppercase; color: var(--th); white-space: nowrap;
}
.bang td { padding: 13px 12px; border-bottom: 1px solid var(--vien); vertical-align: top; }
.bang tbody tr:last-child td { border-bottom: none; }
.bang .p { text-align: right; white-space: nowrap; font-weight: 700; font-family: "Roboto Mono", monospace; font-variant-numeric: tabular-nums; }
.bang .g { text-align: right; white-space: nowrap; color: var(--muc-mo); font-size: 14px; font-family: "Roboto Mono", monospace; font-variant-numeric: tabular-nums; }
.bang a { text-decoration: none; font-weight: 600; color: var(--muc); }
.bang a:hover { color: var(--sang-muc); }
.bang tr.co-link:hover td { background: var(--th-nen); }
.bang .tick input { margin: 0 8px 0 0; vertical-align: middle; }
.cuon { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.chip {
  display: inline-block; padding: 3px 9px; border-radius: 3px;
  font: 700 11px/1.6 "Roboto Mono", monospace; letter-spacing: .05em; white-space: nowrap;
  border: 1px solid transparent;
}
.chip-nhan { background: var(--nhan-nen);   color: var(--nhan); }
.chip-tuchoi { background: var(--tuchoi-nen); color: var(--tuchoi); }
.chip-cho { background: var(--cho-nen);    color: var(--cho); }
.chip-trung { background: var(--th-nen);     color: var(--th); border-color: var(--th-vien); }
.chip-noi-bat { background: var(--sang); color: var(--tren-sang); }

/* --- Khối không nhận: điểm khác biệt, phải đọc được ngay ------------------ */
.khong-nhan {
  background: var(--tuchoi-nen);
  border: 1px solid color-mix(in srgb, var(--tuchoi) 28%, transparent);
  border-left: 3px solid var(--tuchoi);
  border-radius: var(--r); padding: 24px 26px;
}
.khong-nhan h2 { color: var(--tuchoi); }
.khong-nhan ul { margin: 18px 0 0; padding-left: 20px; }
.khong-nhan li { margin-bottom: 12px; line-height: 1.6; }
.khong-nhan li b { display: block; }

.cam-ket { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
/* Homepage: 2 the dau canh nhau, the cuoi 60%% can giua — doc theo hang ngang
   chu khong keo dai full. Tren mobile (<900px) van xep chong nhu cu. */
@media (min-width: 900px) {
  .cam-ket { grid-template-columns: repeat(2, 1fr); }
  .cam-ket > :last-child { grid-column: 1 / -1; width: 60%; justify-self: center; }
}
.cam-ket .the { border-top: 3px solid var(--th); }
.cam-ket .the strong {
  display: block; margin-bottom: 8px; font-size: 17.5px; font-weight: 700;
  font-family: Roboto, system-ui, sans-serif; letter-spacing: -.018em; line-height: 1.28;
}
/* Số thứ tự lớn mờ sau mỗi cam kết — nhịp thị giác cho hàng ba thẻ giống
   hệt nhau, và cho biết đây là một danh sách đếm được chứ không phải khẩu hiệu. */
.cam-ket .the { position: relative; overflow: hidden; }
.cam-ket .the::after {
  content: attr(data-so); position: absolute; right: 14px; top: 2px;
  font: 700 62px/1 "Roboto Mono", monospace; color: var(--th);
  opacity: .07; pointer-events: none;
}

/* --- Các bước: đánh số vì đây LÀ một trình tự, không phải trang trí ------- */
.buoc {
  display: grid; gap: 1px; background: var(--vien);
  border: 1px solid var(--vien); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--bong);
}
@media (min-width: 760px) { .buoc { grid-template-columns: repeat(4, 1fr); } }
.buoc > div { background: var(--the); padding: 24px 22px; display: grid; gap: 8px; align-content: start; }
.buoc .n {
  font: 700 11px/1 "Roboto Mono", monospace; color: var(--th);
  letter-spacing: .14em; padding-bottom: 10px; border-bottom: 2px solid var(--sang);
  justify-self: start; margin-bottom: 4px;
}
.buoc p { font-size: 14px; color: var(--muc-mo); line-height: 1.6; }
/* Ô trải hết hàng: dùng cho bước lẻ cuối cùng. 1 / -1 nên nó đúng bất kể
   lưới đang mấy cột — số cột đổi theo bề ngang máy. */
.buoc > div.buoc-rong { grid-column: 1 / -1; }

/* Bố cục hai cột kiểu ấn phẩm: chữ chạy bên trái, khối phụ neo bên phải. */
.doi-cot { display: grid; gap: 34px; align-items: start; }
@media (min-width: 900px) { .doi-cot { grid-template-columns: minmax(0, 1fr) 340px; gap: 48px; } }
.doi-cot > .canh { display: grid; gap: 14px; align-content: start; }
@media (min-width: 900px) { .doi-cot > .canh { position: sticky; top: 84px; } }
/* Trừ khi cột phải đang đựng cả danh sách việc: cả cột cao hơn màn hình,
   dính lại là đáy danh sách không bao giờ cuộn tới được. */
@media (min-width: 900px) { .doi-cot > .canh:has(.dv-doc) { position: static; } }

/* --- Khối chữ đi kèm bản vẽ ---------------------------------------------- */
.doi-hinh { display: grid; gap: 34px; align-items: center; }
@media (min-width: 900px) { .doi-hinh { grid-template-columns: minmax(0, 460px) minmax(0, 1fr); gap: 52px; } }
.doi-hinh.lat { direction: rtl; }
.doi-hinh.lat > * { direction: ltr; }

/* Khung đựng bản vẽ. Nền hơi khác nền trang để hình không lửng lơ, và có
   một vạch cyan ở mép trên để nó đọc ra là "hình minh họa" chứ không phải
   một thẻ nội dung khác. */
.hinh-o {
  margin: 0; padding: 26px 24px; background: var(--the);
  border: 1px solid var(--vien); border-radius: var(--r);
  border-top: 3px solid var(--sang); box-shadow: var(--bong);
}
.hinh-o figcaption {
  margin-top: 18px; padding-top: 13px; border-top: 1px solid var(--vien);
  font-size: 12.5px; line-height: 1.55; color: var(--muc-mo);
}

/* Danh sách có gạch đầu dòng riêng: dấu gạch cyan thay cho chấm tròn. */
.gach { list-style: none; margin: 18px 0 0; padding: 0; display: grid; gap: 13px; }
.gach li { position: relative; padding-left: 22px; line-height: 1.6; }
.gach li::before {
  content: ""; position: absolute; left: 0; top: .72em; width: 12px; height: 2px;
  background: var(--sang);
}
.gach li b { font-weight: 600; }

/* --- Bài viết ------------------------------------------------------------
   Thân bài là văn xuôi dài, nên đo bằng SỐ KÝ TỰ chứ không bằng pixel:
   65ch là chiều dài dòng mắt còn bắt được đầu dòng sau khi xuống hàng. */
/* Danh sách "đọc tiếp" ở cột bên bài viết. */
.lien-quan { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 0; }
.lien-quan li { border-top: 1px solid var(--vien); }
.lien-quan li:first-child { border-top: none; }
.lien-quan a {
  display: block; padding: 11px 0; font-size: 14px; line-height: 1.45;
  color: var(--muc); text-decoration: none;
}
.lien-quan a:hover { color: var(--sang-muc); }

/* Danh sách bài: xếp hai cột từ 860px trở lên, riêng bài đầu chiếm cả hàng.
   Bài đầu là bài trụ — người mới vào nên đọc nó trước, nên nó được nằm riêng
   một hàng thay vì lẫn vào lưới. */
.bv-luoi { display: grid; gap: 16px; }
@media (min-width: 860px) {
  .bv-luoi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
  .bv-luoi > :first-child { grid-column: 1 / -1; }
}
.bv-the { display: flex; flex-direction: column; align-items: stretch; overflow: hidden; padding: 0; }
.bv-the .bv-noi { display: flex; flex-direction: column; align-items: flex-start; padding: 22px; flex: 1; }
.bv-the .bv-noi > :last-child { margin-top: auto; padding-top: 14px; }
.bv-anh { display: block; overflow: hidden; aspect-ratio: 16 / 9; background: var(--kem-2); }
.bv-anh img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .35s ease; }
.bv-the:hover .bv-anh img { transform: scale(1.03); }
.bv-the h2 { font-size: clamp(19px, 2.2vw, 23px); line-height: 1.3; }
.bv-the h2 a { color: var(--muc); text-decoration: none; }
.bv-the h2 a:hover { color: var(--sang-muc); text-decoration: underline; }

.bai { max-width: 65ch; font-size: 16.5px; line-height: 1.75; color: var(--muc); }
.bai > p { margin-top: 16px; }
.bai > p.dat { font-size: 18px; line-height: 1.7; color: var(--muc-mo); margin-top: 0; }
.bai h2 {
  font-size: clamp(21px, 2.5vw, 26px); line-height: 1.25;
  margin-top: 42px; padding-top: 20px; border-top: 1px solid var(--vien);
}
.bai h3 { font-size: 17.5px; line-height: 1.35; margin-top: 30px; color: var(--sang-muc); }
.bai h3 + p { margin-top: 10px; }
.bai ol,
.bai ul { margin-top: 16px; padding-left: 22px; display: grid; gap: 12px; }
.bai li { padding-left: 4px; }
.bai li::marker { color: var(--sang-muc); font-weight: 600; }
/* Markdown xuất gạch đầu dòng ra <ul class="gach">, mà .gach nằm TRÊN hai dòng
   kia trong tệp này và cùng độ đặc hiệu — nên trong bài, .bai li thắng và thổi
   bay padding-left: 22px của .gach. Vạch 12px vẽ ở left: 0 rơi đúng lên chữ.
   Hai dòng dưới trả lại chỗ cho vạch, đặt sau nên chắc chắn thắng. */
.bai ul.gach { padding-left: 0; }
.bai .gach li { padding-left: 22px; }
.bai strong { font-weight: 600; }
.bai em { color: var(--muc-mo); font-style: italic; }
.bai a { color: var(--sang-muc); }

/* Bản vẽ chèn giữa bài: cho phép tràn rộng hơn cột chữ, vì 65ch là bề rộng
   cho MẮT ĐỌC CHỮ, còn hình thì cần chỗ. */
.bai .hinh-o { margin: 36px 0 4px; max-width: none; }
@media (min-width: 1040px) { .bai .hinh-o { margin-left: -40px; margin-right: -40px; } }

/* Ô nhấn giữa bài: chỗ nói thẳng một điều quan trọng, không phải trích dẫn. */
.bai .luu-y {
  margin: 32px 0 0; padding: 20px 24px;
  background: var(--th-nen); border-left: 3px solid var(--sang);
  border-radius: 0 var(--r-nho) var(--r-nho) 0;
  font-size: 16px; line-height: 1.65; color: var(--muc);
}
.bai .luu-y b { font-weight: 650; }

/* Mục lục neo ở cột phải. Bài dài 1400 chữ mà không có mục lục thì người đọc
   không biết mình đang ở đâu, và Google cũng không thấy được cấu trúc. */
.muc-luc { font-size: 13.5px; }
.muc-luc ol { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 2px; counter-reset: ml; }
.muc-luc a {
  display: block; padding: 7px 10px 7px 30px; border-radius: var(--r-nho);
  text-decoration: none; color: var(--muc-mo); position: relative; line-height: 1.4;
}
.muc-luc a::before {
  counter-increment: ml; content: counter(ml, decimal-leading-zero);
  position: absolute; left: 9px; top: 8px;
  font: 700 10px/1.4 "Roboto Mono", monospace; color: var(--sang-muc); opacity: .75;
}
.muc-luc a:hover { background: var(--th-nen); color: var(--th); }

/* --- Câu hỏi thường gặp ---------------------------------------------------
   Danh sách câu hỏi là MỘT khối liền, không phải mươi cái thẻ rời. .doc-lon
   để cách nhau 30px — đúng cho ba khối khác chủ đề, sai cho mười câu cùng
   một chủ đề: mắt đọc thành mười trang con. Kéo lại còn 12px, và cho câu
   cuối một khoảng thở trước thẻ chốt. */
.doc-lon:has(.ch-muc) { gap: 12px; }
.ch-muc { padding: 20px 22px; }
.ch-muc + .the:not(.ch-muc) { margin-top: 18px; }

/* Neo: mỗi câu có một liên kết #ma để gửi đúng một câu cho khách qua Zalo.
   Nhưng nó không được TRÔNG như liên kết — cả tiêu đề xanh gạch chân thì
   trang thành một rừng link, mà thứ đáng bấm ở đây là câu trả lời bên dưới.
   Nên để nguyên màu chữ, chỉ hiện dấu # khi rê chuột vào cả thẻ. */
.ch-muc h3 { margin: 0; font-size: 17px; line-height: 1.45; }
.ch-neo { color: inherit; text-decoration: none; position: relative; }
.ch-neo::after {
  content: "#"; position: absolute; margin-left: 8px;
  color: var(--sang-muc); opacity: 0; transition: opacity .15s;
}
.ch-muc:hover .ch-neo::after,
.ch-neo:focus-visible::after { opacity: .7; }

/* Nhảy tới một câu qua #ma: đẩy xuống khỏi mép trên để tiêu đề không dính
   sát viền màn hình, và nháy nền một nhịp để mắt biết mình vừa tới câu nào. */
.ch-muc { scroll-margin-top: 86px; }
.ch-muc:target { border-color: var(--sang); box-shadow: 0 0 0 3px var(--th-nen); }

.ch-dap { margin-top: 10px; color: var(--muc-mo); line-height: 1.7; }
.ch-dap > p { margin: 0; }
.ch-dap > p + p { margin-top: 10px; }
.ch-dap ul, .ch-dap ol { margin: 10px 0 0; padding-left: 20px; }
.ch-dap li + li { margin-top: 4px; }

/* --- Form ---------------------------------------------------------------- */
label { display: block; margin-bottom: 15px; font-size: 14px; font-weight: 500; }
label span.hd { display: block; font-weight: 400; color: var(--muc-mo); font-size: 13px; margin-top: 2px; }
input,
textarea,
select {
  width: 100%; margin-top: 6px; padding: 11px 13px;
  border: 1px solid var(--vien-dam); border-radius: var(--r-nho);
  background: var(--the); color: var(--muc);
  font: 400 15px/1.5 Roboto, system-ui, sans-serif;
}
input[type=checkbox],
input[type=radio] { width: auto; margin: 0 8px 0 0; accent-color: var(--th); }
/* Ô chọn tệp mặc định của trình duyệt cao thấp mỗi nơi một kiểu; kẻ viền
   đứt cho nó ra dáng vùng thả tệp thay vì một cái nút lạc lõng. */
input[type=file] {
  padding: 14px; border-style: dashed; border-color: var(--vien-dam);
  background: var(--nen-2); font-size: 14px; cursor: pointer;
}
input[type=file]:hover { border-color: var(--sang); background: var(--th-nen); }
input[type=file]::file-selector-button {
  margin-right: 12px; padding: 7px 13px; border: 1px solid var(--vien-dam);
  border-radius: var(--r-nho); background: var(--the); color: var(--muc);
  font: 600 13.5px/1 Roboto, system-ui, sans-serif; cursor: pointer;
}
.tep-ds { margin: -6px 0 15px; display: grid; gap: 4px; font-size: 13px; color: var(--muc-mo); }
.tep-ds .nang { color: var(--tuchoi); font-weight: 600; }
/* Vòng focus: nét trong lấy --muc chứ KHÔNG lấy volt. Volt trên nền trắng chỉ
   được 1.3:1 — người gõ bàn phím nhìn không ra đang đứng ở ô nào, mà đây là
   form khách phải điền. --muc thì tự đảo theo nền (18:1 trên trắng, và vẫn
   sáng rõ ở các trang nền tối), nên một dòng này đúng cho cả năm giao diện.
   Quầng volt bên ngoài giữ phần nhận diện, không gánh việc tương phản. */
input:focus,
textarea:focus,
select:focus {
  outline: 2px solid var(--muc); outline-offset: 1px; border-color: var(--muc);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--sang) 55%, transparent);
}
/* Link và nút cũng phải thấy được khi đi bằng phím Tab. Dùng :focus-visible
   để chuột bấm không kéo theo vòng sáng. */
a:focus-visible,
button:focus-visible,
.nut:focus-visible,
input[type=file]:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--muc); outline-offset: 2px; border-radius: 3px;
}
.hero a:focus-visible,
.hero button:focus-visible,
.hero .nut:focus-visible,
header.dau a:focus-visible,
header.dau button:focus-visible,
footer a:focus-visible {
  outline-color: var(--sang-tren-toi);
}
textarea { resize: vertical; min-height: 100px; }
button,
.nut-form {
  padding: 12px 22px; border: none; border-radius: var(--r-nho);
  background: var(--th); color: var(--tren-th);
  font: 700 15px/1 Roboto, system-ui, sans-serif; cursor: pointer;
}
button:hover { background: var(--th-2); }
button:disabled { opacity: .5; cursor: default; }
button:focus-visible,
a:focus-visible { outline: 2px solid var(--sang); outline-offset: 2px; }
button.phu,
.nut-phu { background: transparent; color: var(--muc); border: 1px solid var(--vien-dam); }
button.phu:hover,
.nut-phu:hover { background: var(--th-nen); border-color: var(--th-vien); color: var(--th); }
button.nho { padding: 7px 13px; font-size: 13.5px; }
button.do { background: var(--tuchoi); color: #fff; }
button.do:hover { background: var(--tuchoi); opacity: .88; }
.hang { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.hang > * { flex: 1 1 180px; }
.hang > .co-hep { flex: 0 1 150px; }
/* Ô nhập không có min-width thì không co xuống dưới cỡ mặc định của trình
   duyệt, và hàng tràn ra khỏi màn hình điện thoại. */
.hang input, .hang select { min-width: 0; }

/* --- Hộp gợi ý khách quen ------------------------------------------------
   Trạm tự vẽ danh sách thay cho <datalist>: hộp của trình duyệt mỗi máy một
   kiểu, cỡ chữ nhỏ hơn cả ô nhập, và nó xếp chung hàng với lịch sử gõ form
   nên khách thật nằm lẫn với chữ rác thợ từng gõ nhầm.

   Hộp treo tuyệt đối dưới cả hàng chứ không dưới từng ô: hai ô tên và số
   cùng lọc ra một danh sách, treo dưới ô nào cũng lệch. Trên điện thoại
   hàng gập thành hai dòng, hộp vẫn nằm dưới cùng nên không đè lên ô nào. */
.goiy-khung { position: relative; }
.goiy {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 30;
  background: var(--the); border: 1px solid var(--vien-dam);
  border-radius: var(--r-nho); box-shadow: var(--bong);
  max-height: 296px; overflow-y: auto; padding: 4px;
}
.goiy-dong {
  display: flex; align-items: baseline; gap: 10px; width: 100%;
  padding: 9px 11px; margin: 0; border: 0; border-radius: var(--r-nho);
  background: none; color: var(--chu); font-family: inherit; font-size: 14.5px;
  font-weight: 400; text-align: left; cursor: pointer;
}
.goiy-dong:hover, .goiy-dong.chon { background: var(--nen-2); }
/* Tên và số đứng liền nhau bên trái chứ không dàn ra hai mép: mắt thợ đọc
   một cụm rồi mới liếc sang số đơn, để chúng cách nhau nửa màn hình thì
   dòng nào cũng phải quét ngang một lần. */
.goiy-dong .g-ten {
  flex: 0 1 auto; min-width: 0; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.goiy-dong .g-so {
  flex: 0 0 auto; margin-right: auto;
  font: 400 13px/1.5 "Roboto Mono", monospace; color: var(--chu-mo);
}
.goiy-dong .g-no { flex: 0 0 auto; font-size: 12.5px; color: var(--tuchoi); }
.goiy-dong .g-dem { flex: 0 0 auto; font-size: 12.5px; color: var(--chu-mo); }
/* Màn hẹp: số và số đơn xuống dòng dưới tên thay vì bóp tên còn ba chữ. */
@media (max-width: 520px) {
  .goiy-dong { flex-wrap: wrap; gap: 4px 8px; }
  .goiy-dong .g-ten { flex: 1 1 100%; }
}

.bao { padding: 13px 15px; border-radius: var(--r-nho); margin-bottom: 18px; font-size: 15px; }
.bao-ok { background: var(--nhan-nen);   color: var(--nhan); }
.bao-loi { background: var(--tuchoi-nen); color: var(--tuchoi); }
.bao-luu { background: var(--cho-nen);    color: var(--cho); }
/* Dải "cửa hàng đang hoàn thiện". Đẩy lên trên chứ không xuống dưới như .bao
   mặc định: chỗ nào cũng đứng NGAY SAU địa chỉ, nên khoảng cách phải dính vào
   thứ đứng trước nó, không phải thứ đứng sau.

   Nền lime đặc chứ không dùng .bao-luu vàng nhạt như lúc đầu. Câu này đứng
   ngay dưới dải địa chỉ, mà dải địa chỉ cũng nền kem — hai hộp nhạt kề nhau
   thì mắt gộp thành một mảng và câu quan trọng nhất trang chìm mất. Lime là
   màu duy nhất trên site chỉ dùng cho thứ phải đọc, nên đặt ở đây là khách
   nhìn phát thấy ngay.

   Viền trái dày 4px màu forest: khi Kendy đổi bảng màu ở /qt/giao-dien sang
   "cu" thì --lime thành #D3F02B, sáng hơn nữa — vệt tối bên trái giữ cho dải
   vẫn có mép rõ trên nền sáng, không bị loang ra. */
.tb-chuamo {
  margin: 14px 0 0; padding: 12px 15px;
  border-radius: var(--r-nho); border-left: 4px solid var(--forest);
  background: var(--lime); color: var(--forest);
  font-size: 15px; line-height: 1.5;
}
/* Vế đầu in đậm là chỗ trả lời đúng câu khách đang hỏi ("mở cửa chưa?").
   800 chứ không 700: trên nền lime chữ forest đã rất tương phản, 700 gần như
   không tách khỏi phần chữ thường xung quanh. */
.tb-chuamo strong { font-weight: 800; }

/* Mã yêu cầu hiện sau khi khách gửi ảnh. To và tách hẳn ra: khách phải nhìn
   thấy nó ngay để chụp màn hình, chứ không phải dò trong một câu văn. */
.ma-yc {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 12px; padding: 11px 14px;
  border: 1px dashed currentColor; border-radius: var(--r-nho);
}
.ma-yc > span { font-size: 13px; opacity: .8; }
.ma-yc > b { font-size: 18px; letter-spacing: .04em; user-select: all; }

/* --- Chân trang: đóng trang bằng đúng mảng navy đã mở trang -------------- */
footer {
  background: var(--th-dam); color: var(--tren-dam-mo);
  border-top: none; padding: 48px 0 52px; font-size: 13.5px;
}
footer .cot { display: grid; gap: 26px; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
footer b {
  color: #fff; font-family: Roboto, system-ui, sans-serif; font-size: 17px;
  font-weight: 800; letter-spacing: -.018em;
}
footer .nhan-nho { color: var(--sang-tren-toi, var(--sang)); }
footer a { color: var(--tren-dam); text-decoration: none; display: block; padding: 3px 0; }
footer a:hover { color: var(--sang-tren-toi); }
footer .mo { color: var(--tren-dam-mo); }
/* Hàng icon mạng xã hội. Dùng chung cho chân trang và thẻ liên hệ ở
   /lien-he, nên cỡ và màu để mặc thừa hưởng chỗ đặt; chỉ luật xếp hàng nằm ở
   đây. Bọc dòng vì cột chân trang hẹp 190px là có thật.

   Vùng bấm 34px chứ không bằng đúng icon 20px: đây là link cuối trang, ngón
   tay cái với tới lúc đang cầm điện thoại một tay thì trượt là chuyện thường. */
/* Lùi trái 7px: vùng bấm rộng hơn icon 14px nên nếu để nguyên, hàng icon
   thụt vào so với dòng chữ ngay trên nó. */
.mxh-hang { display: flex; flex-wrap: wrap; gap: 4px; margin: 4px 0 0 -7px; }
.mxh-hang a {
  display: grid; place-items: center; width: 34px; height: 34px;
  padding: 0; border-radius: 9px;
}
.mxh-hang .bt { width: 20px; height: 20px; }
.mxh-hang a:hover { color: var(--sang-tren-toi, var(--sang)); }
footer .mxh-hang a { color: var(--trang); }
footer .day {
  margin-top: 32px; padding-top: 20px;
  border-top: 1px solid rgba(255,255,255,.13); font-size: 12.5px;
}

/* --- Trang quản trị ------------------------------------------------------
   Cột trái dùng navy sâu để tách hẳn khỏi vùng làm việc: nhìn một cái là biết
   đâu là điều hướng, đâu là dữ liệu đang sửa. */
.qt-than { display: grid; grid-template-columns: 224px minmax(0, 1fr); gap: 0; min-height: calc(100vh - 57px); }
@media (max-width: 860px) { .qt-than { grid-template-columns: 1fr; } }
.qt-canh {
  background: var(--th-dam); padding: 20px 14px;
  display: flex; flex-direction: column; gap: 2px;
}
@media (max-width: 860px) { .qt-canh { flex-direction: row; flex-wrap: wrap; } }
.qt-canh a {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 9px 12px; border-radius: var(--r-nho); text-decoration: none;
  color: var(--tren-dam); font-size: 14.5px; font-weight: 500;
}
.qt-canh a:hover { background: rgba(255,255,255,.09); color: #fff; }
.qt-canh a.day {
  background: var(--sang-tren-toi); color: var(--tren-sang-toi); font-weight: 700;
}
.qt-canh .nhom {
  margin-top: 18px; padding: 0 12px 4px; color: var(--tren-dam-mo);
}
.qt-canh .dem {
  font: 700 11px/1.6 "Roboto Mono", monospace; background: var(--tuchoi);
  color: #fff; border-radius: 999px; padding: 0 7px;
}
.qt-canh a.day .dem { background: var(--tren-sang-toi); color: #fff; }
.qt-noi { padding: 28px 26px 64px; min-width: 0; background: var(--nen); }
.qt-dau-trang {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid var(--vien);
}
.qt-dau-trang h1 { font-size: 27px; letter-spacing: -.025em; }
.qt-dau-trang .phai { margin-left: auto; display: flex; gap: 10px; flex-wrap: wrap; }

/* Dải tab của khu Quản lý đơn — xem ui/qt-tabdon.html. Bốn tab nằm trên một
   hàng cuộn ngang ở màn hẹp: xuống dòng thì cái tab đang bật rơi xuống hàng
   hai và không ai nhìn thấy nó nữa. */
.tab-don { margin-bottom: 22px; }
.tab-day {
  display: flex; gap: 4px; overflow-x: auto; border-bottom: 1px solid var(--vien);
  scrollbar-width: none;
}
.tab-day::-webkit-scrollbar { display: none; }
.tab-day a {
  flex: 0 0 auto; padding: 10px 15px 11px; font-size: 14.5px; font-weight: 600;
  color: var(--muc-mo); text-decoration: none; border-bottom: 2px solid transparent;
  margin-bottom: -1px; white-space: nowrap; display: flex; align-items: center; gap: 7px;
}
.tab-day a:hover { color: var(--muc); background: var(--nen-2); }
.tab-day a.day { color: var(--th); border-bottom-color: var(--th); }
.tab-day .dem {
  font: 700 11px/1.6 "Roboto Mono", monospace; background: var(--tuchoi);
  color: #fff; border-radius: 999px; padding: 0 7px;
}

.loc-ky {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 11px 0 0;
}
.loc-ky .nhan-nho { margin: 0; }
.loc-ky select, .loc-ky input { margin: 0; width: auto; }
.loc-ky button { padding: 8px 15px; }
.loc-ky .ky-ten { font-size: 13px; color: var(--muc-mo); }

.luoi-so { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); }
.o-so {
  background: var(--the); border: 1px solid var(--vien); border-radius: var(--r);
  padding: 15px 17px; border-top: 3px solid var(--th);
}
.o-so .v { font: 700 25px/1.1 "Roboto Mono", monospace; font-variant-numeric: tabular-nums; letter-spacing: -.02em; color: var(--th); }
.o-so .t { font-size: 13px; color: var(--muc-mo); margin-top: 4px; }
.o-so.canh-bao { border-top-color: var(--tuchoi); }
.o-so.canh-bao .v { color: var(--tuchoi); }
.o-so.tot { border-top-color: var(--nhan); }
.o-so.tot .v { color: var(--nhan); }

.the-nhom {
  background: var(--the); border: 1px solid var(--vien);
  border-radius: var(--r); overflow: hidden; box-shadow: var(--bong);
}
.the-nhom > h3 {
  padding: 13px 18px; border-bottom: 1px solid var(--th-vien); background: var(--th-nen);
  font: 700 11px/1.5 "Roboto Mono", monospace; letter-spacing: .13em;
  text-transform: uppercase; color: var(--th);
}
.the-nhom > .noi { padding: 18px; }
.the-nhom .bang { font-size: 14.5px; }
.the-nhom .bang th { padding-left: 18px; padding-right: 18px; }
.the-nhom .bang td { padding-left: 18px; padding-right: 18px; }
/* Hàng cộng cuối bảng và dải nút dưới đáy thẻ. Đặt .the-chan trong .the-nhom
   chứ không thả nút ra ngoài thẻ: nút "Xuất CSV" xuất đúng bảng ngay trên nó,
   để cạnh nhau thì không ai nhầm là xuất cả kho. */
.the-nhom tfoot td {
  background: var(--th-nen); border-top: 2px solid var(--th-vien);
  padding-top: 12px; padding-bottom: 12px;
}
.the-chan {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  padding: 12px 18px; border-top: 1px solid var(--vien); background: var(--nen-2);
}

/* Khung xem thử lá thư trước khi gửi. Nền trắng cứng chứ không theo giao diện
   đang chọn: đây là hình lá thư lúc nằm trong hộp thư khách, mà hộp thư nào
   cũng nền trắng — xem theme tối rồi gửi đi là gửi mù. */
.xem-thu {
  background: #fff; color: #1a1c20; border: 1px solid var(--vien); border-radius: 8px;
  padding: 16px; max-height: 62vh; overflow: auto; font-size: 14px; line-height: 1.6;
}
.xem-thu a { color: #1257a8; }
.xem-thu table { width: 100%; border-collapse: collapse; }

.moc { border-left: 1px solid var(--th-vien); padding-left: 17px; display: grid; gap: 13px; }
.moc > div { position: relative; font-size: 14px; }
.moc > div::before {
  content: ""; position: absolute; left: -21px; top: 7px; width: 7px; height: 7px;
  background: var(--the); border: 2px solid var(--th-vien); border-radius: 50%;
}
.moc > div:first-child::before { background: var(--sang); border-color: var(--sang); }
.moc .khi { font: 500 12px/1.4 "Roboto Mono", monospace; color: var(--muc-mo); }

.anh-luoi { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.anh-o { border: 1px solid var(--vien); border-radius: var(--r); overflow: hidden; background: var(--nen-2); }
.anh-o img,
.anh-o video { display: block; width: 100%; height: 130px; object-fit: cover; background: #000; }
.anh-o .duoi { display: flex; align-items: center; gap: 6px; padding: 6px 8px; font-size: 11.5px; color: var(--muc-mo); }
.anh-o form { margin-left: auto; }
.anh-o button { padding: 2px 7px; font-size: 11px; background: transparent; color: var(--tuchoi); border: 1px solid var(--vien); }
.anh-o button:hover { background: var(--tuchoi-nen); }

/* Danh sách ảnh trang chủ ở /qt/anh-trang-chu. Dùng lại khung .anh-o của ảnh
   đơn hàng cho khỏi vẽ lại, nhưng ở đây không phải nút nào cũng là nút xoá —
   phải gỡ màu đỏ và cái margin-left:auto mà .anh-o đặt sẵn. */
.anh-ds {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px; margin-top: 14px;
}
.anh-ds .anh-o img { height: 168px; }
.anh-viec { display: grid; gap: 8px; padding: 9px; }
.anh-viec form { margin-left: 0; }
.anh-ct { display: flex; gap: 6px; }
.anh-ct input { flex: 1; min-width: 0; font-size: 12px; padding: 5px 7px; }
.anh-nut { display: flex; gap: 6px; }
.anh-ds .anh-o button { color: var(--muc-mo); }
.anh-ds .anh-o button:hover { background: var(--nen); }
.anh-nut form:last-child button { color: var(--tuchoi); }
.anh-nut form:last-child button:hover { background: var(--tuchoi-nen); }

/* Phải bó trong .bieu-do: chân trang cũng có .cot (lưới cột link), và một
   .cot trần thì cái gradient này tràn xuống đó thành vệt xanh lạ. */
.bieu-do .cot { background: linear-gradient(90deg, var(--th), var(--sang)); border-radius: 2px; min-height: 3px; }
.bieu-do { display: grid; gap: 9px; }
.bieu-do .dong { display: grid; grid-template-columns: 96px minmax(0,1fr) 112px; align-items: center; gap: 12px; font-size: 13.5px; }
.bieu-do .dong .st { text-align: right; font-family: "Roboto Mono", monospace; font-variant-numeric: tabular-nums; font-weight: 700; }

.tra-loi {
  white-space: pre-wrap; background: var(--the); border: 1px solid var(--vien);
  border-left: 3px solid var(--sang); border-radius: var(--r);
  padding: 17px 19px; margin-top: 14px; font-size: 15px;
}
.can-cu { margin-top: 12px; font-size: 13px; }
.can-cu details { background: var(--the); border: 1px solid var(--vien); border-radius: var(--r); padding: 10px 14px; }
.can-cu summary { cursor: pointer; color: var(--muc-mo); }
.can-cu pre { white-space: pre-wrap; font-size: 12px; margin: 8px 0 0; color: var(--muc-mo); }
.canh-bao-dong {
  background: var(--tuchoi-nen); color: var(--tuchoi);
  border-radius: var(--r-nho); padding: 11px 14px; margin-top: 10px; font-size: 14px;
}
.hang-nut { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 12px; }

.yc { border-bottom: 1px solid var(--vien); padding: 15px 0; }
.yc:last-child { border-bottom: none; }
.yc .d { font-size: 13px; color: var(--muc-mo); }

.trong { text-align: center; padding: 48px 20px; color: var(--muc-mo); }
.trong b { display: block; color: var(--muc); margin-bottom: 6px; font-size: 16px; }

dl.kv { display: grid; grid-template-columns: auto 1fr; gap: 10px 20px; margin: 0; font-size: 14.5px; }
dl.kv dt { color: var(--muc-mo); }
dl.kv dd { margin: 0; font-weight: 500; }

/* Chi tiết đơn: cột việc bên trái, cột tóm tắt bên phải. */
.ct-2cot { display: grid; gap: 18px; grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
@media (max-width: 1000px) { .ct-2cot { grid-template-columns: 1fr; } }
.ct-2cot > div { display: grid; gap: 18px; align-content: start; }


/* ==========================================================================
   ĐIỆN THOẠI
   --------------------------------------------------------------------------
   Đo bằng Chrome DevTools Protocol ở khổ 390x844 có bật giả lập thiết bị
   (scratchpad/do.js). Trang KHÔNG tràn ngang — scrollWidth đúng 390 ở mọi
   trang. Ba lỗi có thật, sửa ở đây:

     1. Đầu trang ăn ~215px: "Trạm Pickle" xuống dòng, dòng mô tả chiếm thêm
        hai dòng nữa, nav sáu mục nằm hai hàng. Trên màn 844px cao thì hero
        gần như không còn chỗ.
     2. Chữ dưới 12px: nhãn mono viết hoa 10.5-11px. Trên màn cầm tay, ngoài
        trời, cỡ đó là đoán chữ chứ không phải đọc.
     3. Vùng bấm dưới 44px (khuyến nghị của Apple; WCAG 2.5.8 chỉ bắt 24px).

   Cỡ chữ desktop giữ nguyên — thang chữ ở đó là cố ý, chỉ nới ở khổ hẹp.
   ========================================================================== */
@media (max-width: 680px) {
  /* --- Đầu trang --- */
  .dau-trong { gap: 10px; padding: 9px 0; }
  .logo { font-size: 17px; gap: 8px; }
  .logo-dau { height: 38px; }
  .logo .logo-4d { height: 38px; }
  .logo-khoi { gap: 2px; }
  .chu-tpic { height: 11px; }
  /* Không cho "Trạm Pickle" gãy làm hai dòng: hai chữ này là tên thương hiệu,
     gãy dòng đọc ra hai thứ khác nhau. */
  .logo-ten { white-space: nowrap; padding-left: 9px; }
  /* Dòng mô tả dài (Chuyên sửa chữa · Thay đế giày Pickleball) ăn hai dòng
     nữa mà không nói thêm gì so với chính trang đang mở — bỏ ở khổ này. */
  .logo-phu { display: none; }
  /* Một hàng cuộn ngang, không phải hai hàng xuống dòng. Bảy mục nav gãy làm
     hai hàng thì dải đầu trang cao ~150px trên MỌI trang — một phần sáu màn
     hình cầm tay tiêu trước khi đọc được chữ đầu tiên, và cụm hai hàng ấy
     nặng hơn hẳn cái logo bên trên nó, nhìn ra ngay là lệch.
     Cuộn ngang giữ đủ bảy mục và giữ nguyên vùng bấm 44px, chỉ đổi cách xếp.

     Tràn ra sát mép máy bằng cách ăn ngược lề 24px của .khung: mục cuối lòi
     ra một nửa ở mép phải, đó là dấu hiệu duy nhất cho biết còn cuộn được.
     Gọn trong lề thì mục cuối đứng cách mép một khoảng trắng, trông như đã
     hết mục. Âm lề đúng bằng padding nên hộp nav vẫn bằng hộp .khung —
     không đẻ ra thanh cuộn ngang cho cả trang.
     Không áp phần tràn cho đầu trang quản lý: ở khổ 860 nav bên ấy co lại
     còn một nút và đẩy sang phải bằng margin-left:auto. */
  .dau-trong nav {
    width: 100%; margin-left: 0; gap: 0 4px;
    flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  .dau-trong nav::-webkit-scrollbar { display: none; }
  .dau-trong:not(.qt-dau-trong) nav { margin-inline: -24px; padding-inline: 24px; }
  .dau-trong nav a {
    font-size: 14px; padding: 11px 9px;
    display: inline-flex; align-items: center; min-height: 44px;
    flex: none; white-space: nowrap;
  }
  .nut-nho,
.dau-trong nav a.nut-nho { padding: 11px 15px; min-height: 44px; }

  /* --- Cỡ chữ nhỏ nhất --- */
  .nhan-nho { font-size: 12px; letter-spacing: .13em; }
  .bang-so .n { font-size: 12px; letter-spacing: .12em; }
  .chip { font-size: 12px; padding: 4px 9px; }
  .nho { font-size: 13.5px; }
  /* Nhãn mono viết hoa còn lại — cùng một họ chữ, cùng một lý do. */
  .phieu .dinh,
.bang th,
.buoc .n,
.the-nhom > h3 { font-size: 12px; letter-spacing: .12em; }
  .muc-luc a::before { font-size: 11px; }

  /* --- Vùng bấm --- */
  .nut { padding: 14px 24px; min-height: 44px; }
  button,
.nut-form,
input[type=submit] { min-height: 44px; }
  /* Trừ chấm slider: nó đã tự lo vùng bấm bằng viền trong suốt, ép cao 44px
     vào đây là kéo dài cả hàng chấm. */
  .ba-cham button { min-height: 0; }
}

/* ==========================================================================
   QUẢN LÝ TRÊN ĐIỆN THOẠI — app cài lên màn hình chính
   --------------------------------------------------------------------------
   Bản cũ đổ nguyên cột menu 25 mục ra thành một khối chữ nằm ngang trên đầu
   trang: hết trọn màn hình đầu tiên chỉ để đọc menu, cuộn xuống mới thấy đơn.
   Trong app (không thanh địa chỉ, không nút Back của trình duyệt) thì càng
   sai — mở app ra phải thấy việc, không phải thấy mục lục.

   Ba thay đổi, đều chỉ sống ở màn hẹp:
     1. Cột menu thành ngăn kéo, mở bằng nút ☰ trên đầu.
     2. Thanh bốn nút cố định dưới đáy cho việc hay mở nhất.
     3. Bảng đơn xếp lại thành thẻ, khỏi phải cuộn ngang mới thấy cột tiền.

   Bản máy tính không đổi một pixel nào.
   ========================================================================== */
.qt-menu { display: none; }
/* Mục chỉ dành cho ngăn kéo ở màn hẹp — trên máy tính nó đã nằm sẵn ở
   dải đầu trang, để cả hai chỗ là thừa. Phải viết kèm .qt-canh: luật
   .qt-canh a phía trên đã đặt display, một lớp trơ không đè nổi. */
.qt-canh a.qt-chi-hep { display: none; }
.qt-thanh { display: none; }
.qt-nen { display: none; }

/* Nút cài app dưới đáy menu. Kiểu viền mảnh: nó là thứ bấm một lần trong đời
   máy, đừng tranh chỗ với mục điều hướng ngay trên nó. */
.qt-cai {
  margin: 20px 4px 4px; padding: 11px 12px;
  background: none; border: 1px solid rgba(255,255,255,.28); border-radius: var(--r-nho);
  color: var(--tren-dam); font-size: 13.5px; font-weight: 600;
  cursor: pointer; text-align: left; line-height: 1.35;
}
.qt-cai:hover { background: rgba(255,255,255,.09); color: #fff; }
/* Nhánh iPhone: đổi thành dòng chỉ đường, không bấm được. Bỏ hẳn dáng nút để
   khỏi ai ngồi bấm mãi chờ nó nảy ra hộp thoại. */
.qt-cai-chu, .qt-cai-chu:hover {
  border-style: dashed; cursor: default; background: none;
  color: var(--tren-dam-mo); font-weight: 500;
}

@media (max-width: 860px) {
  .qt-menu {
    display: flex; flex-direction: column; justify-content: center; gap: 4px;
    flex: none; width: 44px; height: 44px; padding: 0 10px; margin-left: -8px;
    background: none; border: none; cursor: pointer;
  }
  /* Còn mỗi nút Thoát thì cho nó ngồi cùng hàng với logo. Luật ở khổ 680
     bẻ nav xuống dòng riêng — đúng cho đầu trang khách (bốn năm mục),
     nhưng ở đây là phí trọn một dòng cho một cái nút. */
  .qt-dau-trong nav { width: auto; margin-left: auto; }
  .dau-trong nav a.qt-an-hep { display: none; }
  .qt-canh a.qt-chi-hep { display: flex; }
  .qt-menu i { display: block; height: 2px; background: var(--tren-dam); border-radius: 2px; }
  body.qt-mo .qt-menu i { background: var(--sang-tren-toi); }

  /* Ngăn kéo phủ kín chiều cao, kể cả dải đầu trang: menu mở ra là đang chọn
     đường đi, lúc ấy không cần nhìn thấy gì khác. */
  .qt-canh {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 60;
    width: min(272px, 82vw); overflow-y: auto;
    flex-direction: column; flex-wrap: nowrap;
    padding: 16px 12px calc(20px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 0 40px rgba(0,0,0,.45);
    transform: translateX(-102%); transition: transform .18s ease;
  }
  body.qt-mo .qt-canh { transform: none; }
  .qt-canh a { min-height: 44px; font-size: 15px; }
  /* Bấm ra ngoài là đóng. Nền mờ để phần trang phía sau lùi hẳn xuống, chứ
     không lẫn với chữ trong menu. */
  .qt-nen {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(8, 12, 18, .45);
  }
  /* Menu mở thì khoá cuộn nền: kéo trong ngăn kéo mà trang sau lưng cũng
     chạy theo là mất phương hướng. */
  body.qt-mo { overflow: hidden; }

  .qt-than { min-height: 0; }
  .qt-noi { padding: 18px 14px calc(78px + env(safe-area-inset-bottom, 0px)); }

  .qt-thanh {
    display: grid; grid-template-columns: repeat(4, 1fr);
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
    background: var(--the); border-top: 1px solid var(--vien);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .qt-thanh a {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    min-width: 0; padding: 9px 3px 10px; text-decoration: none;
    color: var(--muc-mo); font-size: 11.5px; line-height: 1.2; text-align: center;
  }
  .qt-thanh a.dang { color: var(--sang-muc); font-weight: 650; }
  .qt-thanh a:active { background: var(--th-nen); }
  .qt-thanh .bt { width: 22px; height: 22px; }
  /* Đầu trang gọn lại: trong app không có thanh địa chỉ nên dòng này là tất
     cả những gì thấy trên đỉnh — để nó cao ba dòng là phí màn hình. */
  .qt-noi .qt-dau-trang h1 { font-size: 22px; }
}

/* Bảng đơn thành thẻ. Chỉ ở khổ hẹp nhất: từ 680px trở lên bảng chín cột vẫn
   đọc được, mà thẻ thì cao gấp bốn. */
@media (max-width: 680px) {
  .bang-the thead { display: none; }
  .bang-the, .bang-the tbody, .bang-the tr, .bang-the td { display: block; width: 100%; }
  .bang-the tr {
    border: 1px solid var(--vien); border-radius: var(--r);
    padding: 10px 13px; margin-bottom: 10px; background: var(--the);
  }
  .bang-the tr:last-child { margin-bottom: 0; }
  .bang-the td {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    border: none; padding: 3px 0; text-align: right;
  }
  /* Tên cột lấy thẳng từ data-n trên ô — bảng và thẻ dùng chung một nguồn
     chữ, sửa tên cột ở template là cả hai đổi theo. */
  .bang-the td::before {
    content: attr(data-n); flex: none; text-align: left;
    color: var(--muc-mo); font-size: 12.5px; font-weight: 500;
  }
  /* Ô đầu KHÔNG có data-n là tên của cả thẻ (mã đơn, tên vật tư, tiêu đề
     bài): to, không nhãn, gạch chân tách khỏi phần thân. Bảng nào ô đầu cũng
     cần nhãn mới hiểu (sổ tiền mở bằng cột Ngày) thì cứ gắn data-n, thẻ thành
     một danh sách nhãn phẳng, không có dòng tiêu đề. */
  .bang-the td:first-child:not([data-n]) {
    display: block; text-align: left; padding-bottom: 8px; margin-bottom: 6px;
    border-bottom: 1px solid var(--vien); font-size: 16px;
  }
  /* Ô trống thì bỏ hẳn dòng. Bảng có cột Thu và cột Chi, mỗi khoản chỉ dùng
     một trong hai — in cả nhãn "Thu" rỗng lên thẻ là bắt đọc một dòng không
     mang tin gì. */
  .bang-the td:empty { display: none; }
  /* Dòng "chưa có gì" trải hết bảng: không phải tiêu đề thẻ, đừng kẻ gạch. */
  .bang-the td[colspan] {
    justify-content: flex-start; border-bottom: none;
    margin-bottom: 0; font-size: inherit;
  }
  /* Ô nhập trong thẻ ăn hết phần bên phải. Không có luật này thì input co
     lại bằng cỡ mặc định của trình duyệt, gõ ngày vào không nhìn thấy. */
  .bang-the td input:not([type="checkbox"]):not([type="radio"]),
  .bang-the td select, .bang-the td textarea { width: 100%; }
  .bang-the td:has(input[type="date"]), .bang-the td:has(input[type="text"]),
  .bang-the td:has(input:not([type])), .bang-the td:has(select), .bang-the td:has(textarea) {
    display: block; text-align: left;
  }
  .bang-the td:has(input[type="date"])::before, .bang-the td:has(input[type="text"])::before,
  .bang-the td:has(input:not([type]))::before, .bang-the td:has(select)::before,
  .bang-the td:has(textarea)::before { display: block; margin-bottom: 3px; }
  /* Ô nút (Xoá, Đã trả) không có nhãn: cho nút tự trải, ngón tay bấm dễ hơn
     là một nút con con nép ở mép phải. */
  .bang-the td:not([data-n]):not(:first-child) { padding-top: 8px; }
  .bang-the td:not([data-n]) .nut-nho { width: 100%; }
  .bang-the td .nho.mo.so { display: inline; margin-left: 6px; }
  /* Ô "hẹn trả" mang sẵn class chip để nổi lên giữa bảng. Kéo rộng cả dòng
     thì nó thành một vệt hồng dài — bỏ nền, giữ đúng màu chữ báo trễ. */
  .bang-the td.chip { background: none; border: none; border-radius: 0; font-weight: 650; }
  .bang-the .cuon, .cuon:has(.bang-the) { overflow: visible; }
  /* Hàng ngang trong form: ô nào không tự khai là hẹp thì cho ăn trọn bề
     ngang. Nhét ba ô cạnh nhau trên màn 390px thì ô nào cũng bé quá không
     gõ được. */
  .hang > *:not(.co-hep):not(button) { flex-basis: 100%; }
}

/* Màn "mất mạng" của app quản lý (ui/qt-matmang.html). */
.mm { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 24px; }
.mm-o { max-width: 380px; text-align: center; display: grid; gap: 12px; justify-items: center; padding: 30px 24px; }
.mm-o h1 { font-size: 22px; letter-spacing: -.02em; }
.mm-o p { font-size: 14px; color: var(--muc-mo); line-height: 1.55; margin: 0; }
.mm-bt .bt { width: 40px; height: 40px; color: var(--muc-mo); }
.mm-o .nut { margin-top: 8px; }
{{/* Đơn vị đo đi sau con số. Chữ "g" cùng cỡ 42px mà lại là font mono thì dấu
     cách rộng bằng cả một ký tự — nhìn thành hai thứ rời nhau. */}}
.bang-so .v i {
  font-style: normal; font-size: .5em; margin-left: .1em;
  color: var(--muc-mo); letter-spacing: 0;
}

/* --- Hero kiểu tấm phủ: chữ lớn bên trái, hình vẽ lớn bên phải -------------
   Tham chiếu dựng hero bằng một đoạn phim quay thật. Chưa có phim thì chỗ đó
   phải có thứ khác giữ được nửa màn hình — ở đây là bản vẽ cây vợt cỡ lớn,
   nét tự chạy khi tải trang. Hình vẽ không thay được phim, nhưng nó nói được
   một điều mà ảnh chụp không nói được: bên trong cây vợt có gì. */
.hero-lon > .khung {
  padding: clamp(40px, 5vw, 78px) clamp(24px, 4vw, 56px) clamp(44px, 5vw, 74px);
  background: radial-gradient(120% 130% at 78% 8%, #191532 0%, #110E22 46%, #090814 100%);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: 26px;
}
@media (max-width: 680px) { .hero-lon > .khung { border-radius: 18px; } }
.hero-lon h1 { max-width: 15ch; margin-top: 20px; color: #fff; }
.hero-lon .dan { max-width: 46ch; }
.hero-lon .hero-nut { margin-top: 34px; }
/* Hai cột: trái là chữ RỒI ảnh xếp dọc, phải là danh sách việc bắt đầu ngay
   từ đỉnh. Bố cục cũ nhét cả ảnh lẫn danh sách việc vào cột phải, chồng lên
   nhau — cộng lại cao hơn một màn hình, mà ảnh thì bị bóp còn bằng con tem.
   Tách ra: danh sách việc giữ cột phải, ảnh xuống dưới chữ nên rộng gần hết
   bề ngang. */
.hero-canh { display: grid; gap: 34px; align-items: start; }
/* Cột việc 340px vừa đủ cho tên việc dài nhất ("Tinh chỉnh cân bằng bằng lead
   tape") không xuống dòng. */
@media (min-width: 980px) {
  .hero-canh { grid-template-columns: minmax(0, 1fr) minmax(0, 340px); gap: 40px; }
}
.hero-trai { display: grid; gap: clamp(24px, 3vh, 40px); min-height: 0; }
.hero-trai > * { min-width: 0; }
{{/* min-width:0 là bắt buộc, không phải cho đẹp. Ô lưới mặc định rộng tối thiểu
     bằng nội dung, mà SVG hero có kích thước gốc 440px — trên màn 430px thì cả
     trang bị đẩy tràn ngang, chữ cột trái cụt mất mép phải. */}}
.hero-canh > * { min-width: 0; }
/* --- Danh sách việc trong hero -------------------------------------------
   Kính mờ chứ không phải thẻ đặc: hero có ảnh trạm làm nền, đặt một tấm đục
   lên là che mất thứ đắt nhất của trang. Nền mờ 12% cho chữ đủ tương phản mà
   ảnh vẫn xuyên qua. */
.hero-dv {
  display: grid; gap: 1px;
  background: rgba(255,255,255,.14);
  border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--r); overflow: hidden;
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
}
.hero-dv-dinh {
  background: rgba(255,255,255,.10); padding: 12px 16px;
  font: 700 10.5px/1.4 "Roboto Mono", monospace;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--sang-tren-toi, var(--sang));
}
.hero-dv a {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; background: rgba(12,16,32,.42);
  color: #fff; text-decoration: none; font-size: 14.5px; font-weight: 600;
  transition: background .16s, padding-left .16s;
}
/* Mũi tên vẽ bằng ::after chứ không phải ký tự: font hệ thống trên Windows
   hay thay → bằng một ô vuông. */
.hero-dv a::after {
  content: ""; flex: none; width: 7px; height: 7px;
  border-top: 2px solid var(--sang-tren-toi, var(--sang));
  border-right: 2px solid var(--sang-tren-toi, var(--sang));
  transform: rotate(45deg); opacity: .75;
}
.hero-dv a:hover { background: rgba(12,16,32,.66); padding-left: 21px; }
.hero-dv a:hover::after { opacity: 1; }
.hero-dv a:focus-visible { outline: 2px solid var(--sang-tren-toi); outline-offset: -3px; }
.hero-dv-het { font-size: 13px !important; font-weight: 500 !important; color: var(--tren-dam-mo) !important; }
.hero-dv-het:hover { color: #fff !important; }
@media (max-width: 680px) {
  .hero-dv a { padding: 12px 14px; font-size: 14px; }
}
/* Mobile: mot cot, khung khong cat chu, dich vu xuong dong du. */
@media (max-width: 979px) {
  .hero-lon > .khung { overflow: visible; }
  .hero-canh { gap: 22px; }
  .hero-dv a { white-space: normal; overflow-wrap: anywhere; line-height: 1.38; }
  .hero-dv a span { min-width: 0; flex: 1; }
  .hero-dv a::after { margin-left: 10px; }
}
.hero-trai .sv { max-width: 460px; margin: 0 auto; }

/* --- Băng ảnh hero --------------------------------------------------------
   Thay chỗ bản vẽ khi trạm đã up ảnh thật. Khung cố định tỉ lệ 4:3 và ảnh
   cắt theo object-fit: ảnh thợ chụp bằng điện thoại đủ mọi tỉ lệ, để nguyên
   thì mỗi lần đổi ảnh là hero nhảy cao nhảy thấp một kiểu. */
/* Không còn trần chiều ngang: ảnh giờ chiếm gần hết cột trái. Chiều cao mới
   là thứ phải chặn, và chặn ở khối hero-cao-một-màn bên dưới. */
.hero-trai .bang-anh { width: 100%; }
.bang-anh-khung {
  position: relative; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: 18px; border: 1px solid rgba(255,255,255,.13);
  background: rgba(255,255,255,.05);
  box-shadow: var(--bong-cao);
}
.ba-o {
  position: absolute; inset: 0; margin: 0;
  opacity: 0; transition: opacity .7s ease;
}
.ba-o.hien { opacity: 1; }
.ba-o img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Chú thích nằm trên ảnh: ảnh nào cũng có chỗ sáng chỗ tối, nên phải có vệt
   tối đổ lên chứ không thể trông chờ vào màu ảnh. */
.ba-o figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 34px 16px 13px; font-size: 13.5px; line-height: 1.45; color: #fff;
  background: linear-gradient(180deg, transparent, rgba(3,8,4,.86));
}
/* Chấm chỉ 8px, nhưng vùng bấm phải đủ 24x24 (WCAG 2.5.8 Target Size). Cách
   nới: viền TRONG SUỐT 8px cộng background-clip: content-box — nền chỉ tô ô
   nội dung nên chấm vẫn 8px, còn ô nhận ngón tay đã là 24x24. Viền đã tạo
   khoảng cách sẵn nên gap về 0, và margin-top bù lại 8px viền phía trên. */
.ba-cham { display: flex; gap: 0; justify-content: center; margin-top: 6px; }
.ba-cham button {
  -webkit-appearance: none; appearance: none;
  box-sizing: content-box;
  width: 8px; height: 8px; min-width: 0; padding: 0; margin: 0;
  border: 8px solid transparent; background-clip: content-box;
  border-radius: 999px; cursor: pointer; font-size: 0;
  background-color: rgba(255,255,255,.3);
  transition: width .25s ease, background-color .25s ease;
}
.ba-cham button.day { width: 22px; background-color: var(--sang); }

/* Nét chạy dần khi tải trang. Mỗi nét mang pathLength="1", nghĩa là trình duyệt
   coi đường nào cũng dài đúng 1 đơn vị — nhờ vậy một luật dasharray duy nhất
   chạy đúng cho cả nét ngắn lẫn nét dài, không phải đo từng đường. */
@keyframes ve-net { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes hien-dan { from { opacity: 0; } to { opacity: 1; } }
.sv-ve .net {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: ve-net 1.5s cubic-bezier(.6,.05,.3,1) forwards;
}
.sv-ve .cham { animation: hien-dan .8s ease 1.15s both; }
.sv-ve .lop2 { animation-delay: .35s; }
.sv-ve .lop3 { animation-delay: .7s; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .sv-ve .net { stroke-dashoffset: 0; }
  .sv-ve .cham { opacity: 1; }
}
body header.dau { background: var(--th-dam); border-bottom: 1px solid rgba(255,255,255,.10); }
body .hero-lon > .khung {
  background: radial-gradient(120% 130% at 78% 8%, var(--th-2) 0%, var(--th-dam) 74%);
  border: 1px solid rgba(255,255,255,.10);
}

/* Đo trên trang mẫu: tiêu đề Manrope 72px/700 line-height 1.2, thân Inter
   18px/500 — thân bài to hơn hẳn mức thường; nút bo 12px, đệm 14px 24px, nét
   500; khối thở 150px/150px; và điểm riêng nhất: các ô KHÔNG có bóng, KHÔNG
   có viền — chúng là những MẢNG MÀU PHẲNG luân phiên (chàm / vàng nắng / kem).
   Bộ này vì thế đi ngược cả năm bộ kia: mềm, to, phẳng. */
body {
  --r: 14px; --r-nho: 10px; --r-lon: 22px;
  font-size: 17px;
}
body h1 { font-size: clamp(33px, 5vw, 58px); line-height: 1.16; letter-spacing: -.026em; font-weight: 700; }
body h2 { font-size: clamp(24px, 3vw, 36px); line-height: 1.18; letter-spacing: -.022em; font-weight: 700; }
body .nut { border-radius: 12px; padding: 15px 24px; font-size: 16px; font-weight: 600; }
body .nut-nho,
body .dau-trong nav a.nut-nho { border-radius: 10px; }
body .dau-trong nav a { border-radius: 10px; }
body .dv-the .bt-o { border-radius: 14px; }
body section { padding: 100px 0; }
/* Mẫu chia khối bằng khoảng trống lớn, không bằng đường kẻ. */
body section + section { border-top: none; }
body .the { border: none; box-shadow: none; background: var(--nen-2); border-radius: 14px; }
body .luoi-vach,
body .buoc {
  background: none; border: none; box-shadow: none; border-radius: 0; gap: 16px;
}
body .luoi-vach > *,
body .buoc > div { border-radius: 14px; }
/* Ba màu luân phiên như mẫu. nth-child chứ không phải class vì HTML dùng
   chung cho mọi giao diện — không đổi template chỉ để đổi màu ô.
   Ô thứ ba KHÔNG lấy --nen-2: nền trang của bộ này đã là kem, hai màu trùng
   nhau nên ô thứ ba trông như một lỗ thủng giữa lưới. Pha vàng nắng vào nền
   thẻ cho nó là một mảng thật. */
body .luoi-vach > *:nth-child(3n+2) { background: var(--th-nen); }
body .luoi-vach > *:nth-child(3n) { background: color-mix(in srgb, var(--sang) 15%, var(--the)); }
body .buoc > div { background: var(--nen-2); }
body .luoi-vach .dv-the:hover {
  background: color-mix(in srgb, var(--sang) 30%, var(--the)); box-shadow: none;
}
/* Nút "Tra cứu đơn" nằm sẵn trong <nav> nên nó tự đi xuống tầng hai cùng các
   link — đúng chỗ cần, không phải kéo ra góc phải. */

/* --- kem: khung rộng 1296px, hero một cột căn trái, hình thành băng dưới -- */
/* Đo được: cột nội dung của mẫu webflow rộng 1296px chứ không phải 1140, và
   hero cao đúng một màn hình với chữ bắt đầu ở x=72 — tức chữ chạy hết bề
   ngang cột, không có hình đứng cạnh. */
/* width: calc(100% - 40px) chứ không chỉ max-width. Màn 1280px mà khung rộng
   1296px thì khung chạm hai mép: tấm hero mất bo góc, nút "Tra cứu đơn" ở đầu
   trang bị cắt cụt. Có dòng width thì máy nào hẹp hơn 1336px vẫn còn lề. */
body .khung { max-width: 1296px; width: calc(100% - 40px); }
@media (min-width: 980px) {
  /* Hai cột chứ không còn một: cột phải giờ có danh sách việc bấm được,
     để một cột thì nó rơi xuống dưới ảnh và khách phải kéo mới thấy —
     đúng cái phải sửa. Cột phải 360px vừa đủ cho tên việc dài nhất
     ("Tinh chỉnh cân bằng bằng lead tape") không xuống dòng. */
  /* Không chặn bề ngang cột trái: chặn 980px là chặn luôn băng ảnh, mà ảnh
     to là thứ Kendy yêu cầu. Bề ngang chữ đã có h1/dan tự chặn theo số ký
     tự — đó mới là chỗ cần chặn để còn đọc được. */
  body .hero-lon h1 { max-width: 20ch; }
  body .hero-trai .sv { max-width: 560px; width: 100%; margin: 0; }
  body .hero-lon > .khung { padding-block: clamp(48px, 5vw, 76px); }
}

/* --- Tấm hero phải nằm gọn trong MỘT màn hình ---------------------------- */
/* Đây là lần sửa thứ ba. Hai lần trước hỏng vì cùng một sai lầm: tôi ĐOÁN chỗ
   trống còn lại rồi ghi thẳng con số vào CSS.

   - Lần 1: height cứng + minmax(0,1fr). Gặp .hero > .khung { overflow: hidden }
     (css.html:340) thì phần thừa bị CẮT chứ không đẩy trang dài ra — mất hẳn
     hàng nút mà không có thanh cuộn nào báo.
   - Lần 2: bỏ height, đo riêng băng ảnh bằng calc(100svh - 580px). Sai hai chỗ:
     580px là con số tôi nhẩm, mà chiều cao khối chữ lại đổi theo BỀ NGANG cửa
     sổ — cửa sổ hẹp thì h1 xuống ba dòng, mọi con số nhẩm sẵn đều lệch.
   - Và cái không ai ngờ: `body section { padding: 100px 0 }` áp cho MỌI
     section, hero là <section> nên dính đủ 200px trên dưới. Tôi trừ 92px trong khi thực tế phải trừ gần 300px.

   Lần này không đoán nữa. Khung có chiều cao xác định để hàng 1fr có mốc chia,
   CỘNG min-height: fit-content làm van an toàn — chữ dài quá thì khung tự cao
   thêm, nên overflow: hidden không còn gì để cắt. Ảnh nhận đúng phần CÒN DƯ,
   bao nhiêu cũng được, không cần ai nhẩm hộ. Đúng thứ tự đã chốt: co ảnh
   trước, chữ nhỏ lại chút, không bỏ khối nào. */
@media (min-width: 980px) {
  /* Gỡ 200px đệm mà luật nền phát cho mọi section. Hero là tấm duy nhất bắt
     buộc nằm gọn một màn; 200px khoảng trắng ở đây là một phần sáu màn hình. */
  body .hero-lon { padding: 24px 0 0; }

  body .hero-lon > .khung {
    display: grid;
    /* 108px = dải đầu trang (~80px) + đệm trên vừa đặt lại (24px). Trần 1040px
       để trên màn 2K ảnh đừng kéo thành tấm dọc — cắt dọc là mất cả cây vợt. */
    height: min(calc(100vh - 108px), 1040px);
    height: min(calc(100svh - 108px), 1040px);
    min-height: -webkit-fit-content;
    min-height: fit-content;
    padding-block: clamp(22px, 2.8vh, 54px);
  }
  /* stretch để cột trái cao bằng khung — có thế hàng 1fr bên trong nó mới có
     mốc mà chia. Riêng danh sách việc giữ align-self: start, không thì tấm
     kính mờ bị kéo dài xuống tận đáy trong khi chỉ có tám dòng chữ. */
  body .hero-canh { align-items: stretch; }
  body .hero-canh > .hero-dv { align-self: start; }

  /* Sàn 150px: ảnh có thể co, nhưng biến mất hẳn thì hero còn mỗi chữ. Chạm
     sàn rồi mà vẫn chật thì fit-content ở trên cho khung cao thêm — cuộn một
     quãng ngắn, chứ không cắt. */
  body .hero-trai {
    grid-template-rows: auto minmax(150px, 1fr);
    gap: clamp(16px, 2.2vh, 32px);
  }
  body .hero-trai > .bang-anh {
    display: grid; grid-template-rows: minmax(0, 1fr) auto; min-height: 0;
  }
  /* Bỏ tỉ lệ 4:3: chiều cao giờ do ô lưới cấp, ảnh cắt theo object-fit như cũ. */
  body .hero-trai .bang-anh-khung {
    aspect-ratio: auto; height: 100%; min-height: 0;
  }

  /* 46ch là bề ngang của bố cục MỘT cột cũ. Cột trái giờ rộng chừng 920px, giữ
     46ch nghĩa là đoạn mô tả chỉ dùng non nửa chiều ngang rồi đổ xuống bảy
     dòng — ăn mất đúng phần đất của băng ảnh. Nới ra là bớt được hai dòng mà
     không cắt chữ nào. Bộ tim để yên: nó canh giữa, dòng dài quá đọc mỏi mắt. */
  body .hero-lon .dan { max-width: 68ch; }

  /* Dòng chữ to nhất trang đang 58px — trên màn rộng nó chiếm gần một phần ba
     chiều cao hero, đẩy ảnh và cả địa chỉ xuống. Hạ xuống 44px vẫn là thứ to
     nhất trang, mà lấy lại được chỗ cho hai dòng mới. Nới max-width theo, không
     thì chữ bé đi lại rơi thành ba dòng — chẳng tiết kiệm được gì. */
  body .hero-lon h1 { font-size: clamp(30px, 3.3vw, 44px); max-width: 24ch; }

  /* Bản vẽ giữ chỗ lúc chưa up ảnh: cùng ô lưới ấy, giữ tỉ lệ gốc. */
  body .hero-trai > .sv-ve {
    min-height: 0; display: grid; align-content: center; justify-items: center;
  }
  body .hero-trai > .sv-ve > svg { max-height: 100%; width: auto; }
}

/* Màn thấp: chữ nhỏ lại theo chiều cao màn. 880px là chỗ bắt đầu chật — trên
   mức đó cỡ chữ gốc vẫn vừa, dưới mức đó mà giữ nguyên thì riêng khối chữ đã
   ăn hết màn, ảnh chạm sàn rồi vẫn phải cuộn. */
@media (min-width: 980px) and (max-height: 880px) {
  body .hero-lon h1 { font-size: clamp(28px, 4.2vh, 44px); }

  body .hero-lon .dan { font-size: clamp(14.5px, 1.9vh, 17px); line-height: 1.55; }

  body .hero-lon .hero-nut { margin-top: clamp(16px, 2.6vh, 34px); }

  /* Màn càng thấp thì càng phải nới ngang: mỗi dòng bớt đi là hai chục pixel
     trả lại cho băng ảnh. */
  body .hero-lon .dan { max-width: 76ch; }
}

/* Laptop 1366x768 và các màn còn thấp hơn: hạ sàn băng ảnh xuống 110px. Giữ
   150px ở đây thì riêng phần chênh ấy đã đủ đẩy hero quá một màn. */
@media (min-width: 980px) and (max-height: 760px) {
  body .hero-trai { grid-template-rows: auto minmax(110px, 1fr); }
}

/* kem: ba mảng màu rời nhau, bo góc to, không viền không bóng — cùng công thức
   với lưới dịch vụ của bộ này. */
body .bang-so-luoi {
  background: none; border: none; box-shadow: none; gap: 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 700px) { body .bang-so-luoi { grid-template-columns: repeat(3, 1fr); } }
body .bang-so-luoi > div { border-radius: var(--r); padding: 26px 28px; }
body .bang-so-luoi > div:nth-child(2) { background: var(--th-nen); }
body .bang-so-luoi > div:nth-child(3) { background: color-mix(in srgb, var(--sang) 15%, var(--the)); }

/* kem: đảo tỉ lệ — hình rộng hơn chữ. Khung bộ này đã 1296px nên bản vẽ có chỗ
   để thở, và đó là thứ duy nhất trên trang chưa được dùng to. */
@media (min-width: 900px) {
  body .doi-hinh { grid-template-columns: minmax(0, 1fr) minmax(0, .74fr); gap: 56px; }
  body .hinh-o { border-radius: 22px; padding: 30px; }
}

/* --- 3. Khối "tiêu đề rồi tới nội dung" ----------------------------------- */
/* Gốc (css.html:237): .doc-lon xếp dọc, tiêu đề trên, nội dung dưới. Dùng ở ba
   mục: bảng dịch vụ, bốn bước, ba cam kết — nên đổi một dòng là đổi ba mục. */

/* kem và do: tiêu đề tách sang một cột trái, nội dung chạy bên phải. Đây là
   đòn đổi dáng trang mạnh nhất trong cả khối này vì nó ăn vào ba mục một lúc.
   Chỉ hai bộ được dùng: kem có khung 1296px và do có lưới một cột, cả hai còn
   chỗ cho cột trái. Bốn bộ kia lưới 3-4 cột, cắt thêm 300px là ô bẹp dí.
   CHÚ Ý: chỉ ăn khi con ĐẦU của .doc-lon thật sự là khối tiêu đề (nhận ra qua
   .nhan-vach bên trong). Bốn trang — dịch vụ, quy trình, bài viết, tra cứu —
   đặt thẳng lưới vào con đầu, không có tiêu đề; thiếu chốt :has() thì lưới bị
   nhét vào cột 320px và thẻ bẹp còn 96px, mỗi dòng một chữ. */
@media (min-width: 1000px) {
  body .doc-lon:has(> *:first-child .nhan-vach) { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 48px; align-items: start; }
}

/* kem: 2x2, các ô rời nhau bo góc to, màu luân phiên. */
body .buoc { background: none; border: none; box-shadow: none; gap: 16px; }
@media (min-width: 760px) { body .buoc { grid-template-columns: repeat(2, 1fr); } }
body .buoc > div { border-radius: var(--r); padding: 28px 26px; }
body .buoc > div:nth-child(2n) { background: var(--th-nen); }

/* kem: ba mảng màu luân phiên, không viền. */
body .cam-ket { gap: 16px; }
body .cam-ket .the { border: none; border-radius: var(--r); padding: 26px 28px; }
body .cam-ket .the:nth-child(2) { background: var(--th-nen); }
body .cam-ket .the:nth-child(3) { background: color-mix(in srgb, var(--sang) 15%, var(--the)); }

/* kem: một cột, form chạy hết khung 1296px, hai thẻ phụ thành hai mảng rộng
   bên dưới. */
@media (min-width: 900px) {
  body .doi-cot:not(:has(> .bai)):not(:has(.dv-doc)) { grid-template-columns: minmax(0, 1fr); }
  body .doi-cot:not(:has(> .bai)):not(:has(.dv-doc)) > .canh { position: static; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
}

/* Trang bài viết là ngoại lệ: nó KHÔNG có form, và thân bài bị chốt ở 65ch cho
   dễ đọc. Nếu để nó chạy hết khung 1296px thì chữ vẫn 65ch còn nửa phải trống
   trơn, còn hai thẻ phụ rơi xuống tận cuối bài. Nên giữ đúng hai cột: chữ neo
   trái, khối phụ neo phải thẳng mép hero, khoảng giữa là lề ấn phẩm. */
@media (min-width: 900px) {
  body .doi-cot:has(> .bai) {
    grid-template-columns: minmax(0, 65ch) minmax(0, 340px);
    justify-content: space-between; gap: 48px;
  }
}
@media (min-width: 900px) {
  body footer .cot { grid-template-columns: 2fr 1fr 1fr; gap: 40px; }
}


/* ==========================================================================
   CHUYỂN ĐỘNG
   --------------------------------------------------------------------------
   Ba thứ, không hơn: nút và thẻ nhấc lên khi rê chuột, mỗi khối nội dung trôi
   lên một quãng ngắn khi cuộn tới, và vệt sáng trên hero thở rất chậm. Trang
   bán hàng cần thấy sống, nhưng thứ nhảy múa quá tay thì đọc mệt, và trên máy
   yếu là giật — mà khách của trạm phần lớn mở bằng điện thoại giữa sân.

   Cả khối này tự tắt trong @media (prefers-reduced-motion: reduce) phía trên,
   vì rule ở đó dùng !important.
   ========================================================================== */
.nut,
.dv-the,
.the,
.bt-o,
.phieu {
  transition: transform .18s ease, box-shadow .22s ease,
              background-color .18s ease, border-color .18s ease, color .18s ease;
}
.nut-chinh:hover,
.nut-vien:hover { transform: translateY(-2px); }
.nut-chinh:active,
.nut-vien:active { transform: translateY(0); }
.nut-chinh:hover {
  box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--sang) 70%, transparent);
}
.dv-the:hover { transform: translateY(-3px); }
/* Trong lưới có vạch ngăn thì thẻ không được nhấc: nhấc lên là hở vạch. */
.luoi-vach .dv-the:hover { transform: none; }

/* Vệt sáng hero thở. 16 giây một nhịp — chậm tới mức không ai bắt được nó
   đang động, chỉ thấy tấm hero không chết cứng. Chỉ animate opacity: ::before
   phủ inset:0 nên scale sẽ tràn khỏi bo góc. */
@keyframes tho-sang { 0%,
100% { opacity: .82; } 50% { opacity: 1; } }
.hero-lon > .khung::before { animation: tho-sang 16s ease-in-out infinite; }

/* Khối nội dung trôi lên khi cuộn tới.
   Trạng thái ẩn ban đầu CHỈ bật khi JS đã chạy và đã gắn class lên body —
   không có JS (hoặc JS lỗi) thì trang vẫn hiện đủ chữ. Ẩn bằng CSS thuần rồi
   trông chờ JS hiện ra là cách nhanh nhất để có một trang trắng. */
@keyframes troi-len { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
body.js-troi .troi { opacity: 0; }
body.js-troi .troi.vao { animation: troi-len .55s cubic-bezier(.22,.68,.36,1) both; }


/* ==========================================================================
   ẢNH, TRANG TRÍ VÀ CHUYỂN ĐỘNG — RIÊNG TỪNG BỘ
   --------------------------------------------------------------------------
   Khối này sinh ra từ một lần bị trả lại: "nó vẫn chỉ là thay màu sắc thôi mà".
   Đo lại thì đúng thật. Trước khối này cả bảy bộ dùng CHUNG bốn @keyframes
   (ve-net, hien-dan, tho-sang, troi-len) và chung đúng một luật rê chuột —
   nghĩa là màu khác, dáng khác, bố cục khác, nhưng trang ĐỘNG y hệt nhau.
   Đo ba mẫu gốc bằng scratchpad/hieuung.js:

     mẫu Compair (cobalt)   30 ảnh · 368 transition · 40 keyframes · WOW+Swiper
     mẫu Gogrin  (đỏ)       12 ảnh · 491 transition · 40 keyframes · WOW+Swiper
     mẫu RepairPress (biển) 12 ảnh ·  79 transition · 11 keyframes · không thư viện
     trang mình               3 ảnh ·  30 transition ·  4 keyframes

   Ba con số đầu tiên mới là chỗ chênh lệch thật: ẢNH. Mẫu nào cũng 12-30 tấm,
   mình có 3 tấm line-art xanh volt dùng chung cho cả bảy bộ. Không có ảnh thì
   sáu trang chỉ còn là sáu cách xếp chữ, mà xếp chữ thì nhìn lướt qua giống
   nhau hết.

   Nên khối này làm ba việc, theo đúng thứ tự sức nặng:

   1. ẢNH. Mỗi bộ hai tấm riêng, nhúng trong binary ở ui/anh/, phục vụ qua
      /anh-gd/{ten}. Gắn bằng background-image chứ không phải thẻ <img>: HTML
      không phải đổi một chữ, và mỗi bộ tự chọn tấm của mình. Ảnh lấy ở
      Unsplash — giấy phép cho dùng thương mại, không bắt ghi nguồn. Đây là
      ảnh ĐỆM: Kendy up ảnh trạm thật vào /qt/anh-trang-chu thì ảnh thật
      thắng ở tấm đầu trang, mấy chỗ còn lại vẫn là ảnh kho cho tới khi có đủ.

   2. TRANG TRÍ. Mỗi bộ một món, không bộ nào trùng bộ nào:
        cobalt  băng ảnh phủ kín dưới dải số
        điện    số to hơn nữa, ảnh làm nền rất mờ sau ba cam kết
        biển    tấm đè lấn — hình có một tấm phẳng lệch 22px sau lưng
        kem     huy hiệu tròn thay ô vuông, băng ảnh ấm ở chân trang
        đỏ      dải ảnh trạm làm kết cấu sau bốn bước
        cam     đường cắt chéo trên tấm đầu trang, ảnh chạy hết bề ngang

   3. CHUYỂN ĐỘNG. Mỗi bộ một hướng hiện, một nhịp, một kiểu rê chuột. Nhịp
      là thứ ít ai gọi tên được nhưng nhận ra ngay: đỏ nảy trong 0.1s, kem
      trôi 0.42s. Cùng một trang, hai cảm giác khác nhau.

   Ba luật giữ khối này không thành trang trí rởm:
     · Chữ trên ảnh luôn có màn lọc bằng chính --th của bộ, đủ dày để tỉ lệ
       tương phản không rơi. Ảnh chỉ được nằm dưới chữ khi có màn lọc.
     · Dưới 900px mọi kiểu cắt chéo/chia đôi đều rơi về "ảnh phủ kín + màn lọc
       dày", vì ở đó chữ chạy hết bề ngang, không còn nửa nào trống để đặt ảnh.
     · Cả khối tự tắt trong prefers-reduced-motion nhờ rule * !important ở trên.
   ========================================================================== */

/* --- Từ vựng chuyển động dùng chung -------------------------------------- */
/* Ảnh nền thở rất chậm. Chỉ transform, không đụng background-size: đổi
   background-size là trình duyệt vẽ lại ảnh mỗi khung hình, điện thoại giữa
   sân là giật ngay. */
@keyframes anh-tho { from { transform: scale(1); } to { transform: scale(1.07); } }

@keyframes troi-trai { from { opacity: 0; transform: translateX(-30px); } to { opacity: 1; transform: none; } }
@keyframes troi-phai { from { opacity: 0; transform: translateX(26px);  } to { opacity: 1; transform: none; } }
@keyframes troi-no   { from { opacity: 0; transform: scale(.945);       } to { opacity: 1; transform: none; } }
@keyframes troi-mo   { from { opacity: 0;                               } to { opacity: 1; } }
@keyframes troi-roi  { from { opacity: 0; transform: translateY(-22px); } to { opacity: 1; transform: none; } }
/* Quét từ trái sang như kéo tờ giấy ra khỏi máy in. Giữ opacity 1 suốt vì
   thứ tạo hiệu ứng là mép cắt, mờ thêm nữa thì mất luôn cái mép ấy. */
@keyframes troi-quet { from { opacity: 1; clip-path: inset(0 100% 0 0); } to { opacity: 1; clip-path: inset(0 0 0 0); } }


/* --- KEM: huy hiệu tròn, băng ảnh ấm ở chân trang ------------------------- */
/* Nửa trái đặc màu tới mốc 46% rồi loãng dần — ảnh gỗ ấm chỉ sáng lên ở nửa
   phải. Bộ này khung rộng 1296px, chữ dẫn 54ch chạy tới quãng 52% bề ngang,
   nên mốc đặc phải là 46% chứ không thấp hơn. Từng để radial 150% ở góc phải
   trên: bán kính lớn quá nên tới giữa tấm màn lọc mới được 40%, chữ xám nằm
   thẳng trên vân gỗ sáng. */
body .hero > .khung::before {
  background:
    linear-gradient(96deg, var(--th-dam) 0 46%, color-mix(in srgb, var(--th-dam) 72%, transparent) 74%, color-mix(in srgb, var(--th-dam) 44%, transparent) 100%),
    url("/anh-gd/kem-hero.jpg") 76% 22%/cover no-repeat;
  animation: anh-tho 40s ease-in-out infinite alternate;
  transform-origin: 78% 20%;
}
/* Món trang trí riêng của kem: HUY HIỆU TRÒN. Ô biểu tượng vuông bo 14px
   thành đĩa tròn có vành màu nhấn. Ô sẵn là 50x50 nên tròn đều, không méo. */
body .dv-the .bt-o {
  border-radius: 50%; border: 2px solid color-mix(in srgb, var(--sang) 45%, transparent);
  background: var(--nen-2);
}
body .dv-the:hover .bt-o { border-color: var(--sang); }
/* ... trừ khi bên trong là hình MÀU. Bộ hình màu (.btm) vốn vẽ cho lưới app:
   mỗi hình đã là một ô vuông bo góc có nền riêng. Lồng nó vào đĩa tròn có
   vành thì thành hai cái nền chồng nhau, và đĩa tròn cắt cụt bốn góc hình.
   Nên ở đây ô chỉ còn là chỗ đặt: hình chiếm trọn 50×50.

   Chỉ nhắm ô CÓ .btm chứ không sửa .bt-o nói chung — ô "Xem tất cả" và mấy
   ô lối-thoát khác vẫn dùng hình nét, chúng vẫn cần cái đĩa làm nền. */
body .dv-the .bt-o:has(.btm),
body .dv-the:hover .bt-o:has(.btm) {
  background: none; border: none; border-radius: 14px; padding: 0;
}
.dv-the .bt-o .btm { width: 100%; height: 100%; }
/* Chân trang đứng trên một băng ảnh ấm. Màn lọc 88% giữ nguyên độ tương phản
   của chữ chân trang — chỗ này chữ đã nhỏ 13.5px, không được phép mờ thêm. */
body footer {
  background:
    linear-gradient(0deg, color-mix(in srgb, var(--th-dam) 88%, transparent), color-mix(in srgb, var(--th-dam) 92%, transparent)),
    url("/anh-gd/kem-bang.jpg") center 35%/cover no-repeat;
}
/* Hiện khi cuộn: trôi từ phải sang, chậm nhất trong sáu bộ (.7s). Bộ này là
   bộ giãn nhất — khối cách nhau 100px — nên chuyển động cũng phải thong thả
   theo, nhanh thì lệch hẳn với khoảng trống xung quanh. */
body.js-troi .troi.vao { animation: troi-phai .7s cubic-bezier(.22,.72,.28,1) both; }
/* Rê chuột: thẻ trượt sang phải, không nhấc. Bộ này thẻ không có viền cũng
   không có bóng, nhấc lên thì chẳng thấy gì thay đổi vì không có mép để nhìn. */
body .dv-the,
body .the,
body .nut { transition-duration: .42s; }
body .dv-the:hover { transform: translateX(6px); background: var(--th-nen); }
body .luoi-vach .dv-the:hover { transform: translateX(6px); }
body .nut-chinh:hover,
body .nut-vien:hover { transform: translateY(-2px); }

/* ==========================================================================
   MÀN HÌNH APP (/app) và thanh mời cài
   Chạy trên body.la-app, tách hẳn khỏi khung web. Mọi màu lấy từ biến --md-*
   khai ở đầu tệp, nên đổi bảng màu gốc là app đổi theo, không sửa chỗ này.
   Riêng màn hình ĐẦU của app dựng lại ở khối cuối tệp — luật ở đây là phần
   dùng chung cho các trang con.
   ========================================================================== */
body.la-app {
  background: var(--nen-2);
  /* Chừa chỗ cho thanh đáy cố định, cộng lề an toàn của iPhone tai thỏ. */
  padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
}
body.la-app main { min-height: 0; }

.app-dau {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 16px calc(10px) 16px;
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  background: var(--the); border-bottom: 1px solid var(--vien);
}
/* --- Bảng hiệu ở màn hình đầu ------------------------------------------
   Logo, tên trạm, dòng nghề — xếp giữa thành một tấm biển. Trước đây ba thứ
   này nằm chen một hàng ngang bên trái, chữ 16px, lọt thỏm cạnh cái logo;
   khách mở app ra không thấy tên trạm đâu.

   Tấm biển này KHÔNG dính đỉnh: nó cao gần trăm điểm ảnh, dính lại thì suốt
   lúc cuộn cứ chiếm mất một phần bảy màn hình để lặp lại thứ khách đã đọc.
   Đường về vẫn còn nguyên ở nút Trang chủ dưới thanh đáy. */
/* --- Hàng rào: chặn luật trang web tràn vào vỏ app ---------------------
   Luật bố cục của trang web khai theo dạng `body <thẻ>` — `body section`,
   `body h1`, `body h2`. Đặc hiệu (0,0,2): thua class, nhưng chỉ khi luật app
   THẬT SỰ có class đụng đúng thẻ đó. Chỗ chết người là luật app viết cho một
   thẻ trần thì thua sạch, nằm sau bao nhiêu dòng cũng vô ích.

   Đã dính một lần và mất công dò: <section class="app-hero"> ăn nguyên
   `section { padding: 100px 0 }`, thành hai khoảng trắng hai trăm điểm ảnh
   kẹp lấy đúng một câu; h1 trong đó nhảy lên 33px, to ngang tên trạm trên
   tấm biển; .app-muc ở trang con cũng phồng y như vậy.

   Không sửa bằng cách hạ luật web xuống: chúng đúng cho trang web trên màn
   24 inch. Dựng hàng rào ở đây thay vào đó — mọi luật trong khối này đều kèm
   body.la-app nên vượt được luật nền, mà không rơi giọt nào ra ngoài, vì lớp
   la-app chỉ có trên các trang /app. Luật app nào đụng cùng một thẻ với luật
   nền thì phải nằm trong hàng rào này, không viết class trần ở ngoài rồi
   mong nó thắng. */
body.la-app .app-than section { padding: 0; border-top: none; }
body.la-app .app-than section.app-muc { padding: 16px 15px 17px; }
body.la-app .app-h2 { font-size: 16px; line-height: 1.3; letter-spacing: -.01em; font-weight: 700; }
body.la-app .app-dv-ten { font-size: 21px; line-height: 1.2; letter-spacing: -.02em; font-weight: 700; }

.app-bia {
  text-align: center;
  padding: calc(20px + env(safe-area-inset-top, 0px)) 16px 18px;
  background: var(--the); border-bottom: 1px solid var(--vien);
}
.app-bia-lk { display: block; text-decoration: none; color: var(--muc); }
/* Bảng hiệu app dùng bản logo-4d. Thân app nền SÁNG, còn mặc định của
   .logo-4d ở trên là bản nền tối (trắng) — để nguyên là chữ trắng trên nền
   trắng, mất hẳn. Cho nó ăn theo mực và màu nhấn của giao diện đang bật,
   đúng như bản phẳng làm ở dưới. KHÔNG khoá aspect-ratio: khung đã cắt sát
   mực nên hình không còn vuông, xem ghi chú ở .logo-dau. */
.app-bia .logo-4d { width: auto; }
body.la-app .app-bia .logo-4d {
  height: 46px; filter: none;
  --l4-chinh: var(--muc); --l4-nhan: var(--lime);
}
body.la-app.man-1 .app-bia .logo-4d { height: clamp(29px, 4.8svh, 40px); }
.app-bia .logo-dau { height: 46px; width: auto; margin: 0 auto; display: block; }
.app-bia .logo-khoi { margin: 0 auto; }
.app-bia .chu-tpic { height: 13px; }
.app-bia img.logo-dau { max-width: 200px; object-fit: contain; }
/* Mặc định của .logo-dau là bản nền tối (trắng). Thân app nền sáng, để
   nguyên là chữ trắng trên nền trắng, mất hẳn. Đổi sang bản ăn theo mực của
   giao diện đang bật; nửa trên mặt vợt vẫn là vàng nhấn — đó chính là bản
   nền sáng của dấu hiệu, không phải bản mono. */
body.la-app .app-bia .logo-dau,
body.la-app .app-dau .logo-dau {
  --lg-chinh: var(--muc); --lg-nhan: var(--lime);
}
/* Thân app nền SÁNG: gạch nối về cùng màu chữ, xem ghi chú ở .chu-tpic. */
body.la-app .chu-tpic { --tp-chu: var(--muc); --tp-gach: var(--muc); }
.app-bia-ten {
  display: block; margin-top: 12px;
  font-size: clamp(23px, 6.6vw, 29px); font-weight: 800;
  letter-spacing: -.03em; line-height: 1.08;
}

.app-than { max-width: 620px; margin: 0 auto; padding: 18px 16px 8px; }
.app-dan { margin: 2px 2px 14px; color: var(--muc-mo); font-size: 14px; line-height: 1.5; }

/* Dòng chữ to nhất màn app. Tên trạm trên đầu trang là tên riêng — nó không
   nói ra nghề, mà khách mới cài xong thì cần biết ngay app này làm gì với cây
   vợt. Cỡ chữ co theo bề ngang máy: máy 320px vẫn hai dòng, không tràn. */
/* Mọi khối trong thân app ăn chung lề của .app-than. Trước đây mỗi khối tự
   thêm 2-3px lề riêng, ba khối ba mép lệch nhau vài điểm ảnh — không ai chỉ
   ra được là lệch, nhưng nhìn vào thấy nó xộc xệch. */
.app-hero { margin: 0 0 20px; }
/* Nhỏ hơn tên trạm trên tấm biển một bậc rõ ràng. Hai dòng chữ to bằng nhau
   cách nhau hai chục điểm ảnh thì không dòng nào còn là dòng to nhất. */
body.la-app .app-hero h1 {
  margin: 0; font-size: clamp(18.5px, 5.2vw, 23px); line-height: 1.2;
  font-weight: 800; letter-spacing: -.022em;
}
.app-hero-chu { margin: 7px 0 0; font-size: 13.5px; line-height: 1.45; color: var(--muc-mo); }
.app-hero-chu b,
.app-hero-chu strong { color: var(--muc); font-weight: 700; }

/* Nhãn nhóm chứ không phải tiêu đề: chữ nhỏ, in hoa, giãn nét. Nó chỉ có
   việc nói mấy ô dưới là gì, không được to bằng câu hero ngay trên. */
.app-nhan-nhom {
  margin: 0 0 10px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--muc-mo);
}

.app-luoi { display: grid; grid-template-columns: repeat(2, 1fr); gap: 11px; }
@media (min-width: 520px) { .app-luoi { grid-template-columns: repeat(3, 1fr); } }

/* Bản nhỏ của lưới, dùng ở màn hình đầu: ba cột, biểu tượng với tên việc,
   không có dòng số ngày. Ô cao 76px thay vì 116px — sáu việc gói trong hai
   hàng, còn chỗ cho ba khối gấp bên dưới nằm cùng một màn hình. Số ngày làm
   vẫn còn nguyên ở trang từng dịch vụ. Khai sau media query trên kia để
   thắng nó, hai bên cùng một mức đặc hiệu. */
/* Bốn cột cố định, hình màu 42px với tên việc bên dưới. Trần 430px cho cả
   lưới: trên máy tính bảng .app-than rộng 620px mà vẫn chia bốn thì mỗi ô
   phình thành khung 150px chứa một hình 42px, nhìn như bảng còn thiếu chữ.
   Tám ô hai hàng luôn đầy — có thêm dịch vụ thì hàng cuối hở vài ô, không
   sao: ô nhỏ nên khoảng hở không thành cái lỗ như hồi ô cao 116px. */
.app-luoi-nho { grid-template-columns: repeat(4, 1fr); gap: 8px; max-width: 430px; margin: 0 auto; }
.app-luoi-nho .app-o {
  align-items: center; justify-content: flex-start; text-align: center;
  min-height: 0; padding: 10px 4px 11px; gap: 6px;
}
.app-luoi-nho .app-bt { display: flex; align-items: center; justify-content: center; }
.app-luoi-nho .app-bt .btm { width: 42px; height: 42px; }
/* Hai dòng là trần. Ở 4 cột trên máy 360px mỗi ô rộng chừng 78px, chữ 11px
   xuống được hai dòng là vừa; tên nào dài hơn thì cắt — hình đã nói việc
   rồi, chữ ở đây chỉ xác nhận. Đặc hiệu (0,2,0) để thắng luật .app-ten
   chung bên dưới, không phải để thắng giao diện. */
.app-luoi-nho .app-ten {
  margin-top: 0; font-size: 11px; line-height: 1.25; font-weight: 600;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Ô vuông cỡ ngón tay: cạnh ngắn nhất vẫn trên 44px kể cả trên máy 320px. */
.app-o {
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  min-height: 116px; padding: 14px 13px;
  background: var(--the); border: 1px solid var(--vien); border-radius: var(--r);
  color: var(--muc); text-decoration: none;
  transition: transform .14s ease, border-color .14s ease, box-shadow .14s ease;
}
.app-o:active { transform: scale(.97); }
.app-o:hover { border-color: var(--vien-dam); box-shadow: var(--bong); }
.app-bt { display: block; color: var(--sang-muc); }
.app-bt .bt { width: 30px; height: 30px; }
.app-bt .btm { width: 32px; height: 32px; }
.app-ten { font-weight: 650; font-size: 14.5px; line-height: 1.25; margin-top: auto; }
.app-phu { font-size: 11.5px; color: var(--muc-mo); }
/* Con số trong ô việc. Mono + tabular-nums để hai ô cạnh nhau có dấu chấm
   nghìn thẳng hàng; white-space:nowrap vì cắt giữa một con số là đọc ra giá
   sai, thà để nó tràn rồi bị ellipsis cắt ở cuối. */
.app-o-gia {
  font: 700 11px/1.2 "Roboto Mono", ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 100%; color: var(--th);
}
.app-luoi-chu {
  margin: 12px 4px 0; font-size: 12px; line-height: 1.5;
  color: var(--muc-mo); text-align: center;
}
.app-o-hoi { border-style: dashed; }
.app-trong { margin: 22px 4px; color: var(--muc-mo); text-align: center; }

.app-chan {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  display: flex; align-items: flex-end;
  background: var(--the); border-top: 1px solid var(--vien);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.app-chan a {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 9px 3px 10px; color: var(--muc-mo); text-decoration: none;
  font-size: 11px; line-height: 1.2; text-align: center;
}
.app-chan a:active { background: var(--th-nen); }
.app-chan a.dang { color: var(--sang-muc); font-weight: 650; }
.app-chan .bt { width: 22px; height: 22px; }
/* Chỉ đường luôn đỏ để nổi trên thanh đáy — chỉ ô này, không chạm 4 nút kia. */
.app-chan a.app-chi-duong { color: #d32f2f; }
.app-chan a.app-chi-duong:active { background: var(--th-nen); }

/* Nút giữa nhô hẳn lên khỏi thanh. Vành 4px cùng màu nền trang để nó trông
   như xuyên qua thanh chứ không dán đè lên. */
.app-chan a.app-chan-tron { padding-top: 0; color: var(--muc); font-weight: 650; }
.app-chan-tron .tron {
  flex: none; width: 54px; height: 54px; border-radius: 50%; margin: -24px 0 1px;
  display: flex; align-items: center; justify-content: center;
  background: var(--sang); color: var(--tren-sang);
  border: 4px solid var(--nen); box-shadow: 0 5px 14px rgba(0, 0, 0, .2);
}
.app-chan-tron .tron .bt { width: 25px; height: 25px; stroke-width: 1.9; }
/* Số điện thoại in thẳng dưới nút. Nhỏ hơn nhãn mấy nút kia vì mười chữ số
   phải lọt vào một ô rộng bằng một phần năm màn hình; tabular-nums cho các
   chữ số đều bề ngang, không so le. */
.app-chan a.app-chan-tron { flex-grow: 1.3; }
.app-chan-so {
  font-size: 10.5px; letter-spacing: -.01em; white-space: nowrap;
  font-variant-numeric: tabular-nums; font-weight: 700;
}

/* Bảng soi máy ở /app/kiem. Chữ nhỏ và cho phép ngắt giữa chừng vì cột phải
   chứa cả chuỗi userAgent dài ngoằng lẫn địa chỉ trang. */
.kiem-ds { margin: 0; font-size: 13px; }
.kiem-ds dt { color: var(--muc-mo); margin-top: 10px; }
.kiem-ds dd {
  margin: 1px 0 0; font-weight: 650;
  overflow-wrap: anywhere; word-break: break-word;
}
.app-chan a.app-chan-tron:active { background: none; }
.app-chan a.app-chan-tron:active .tron { filter: brightness(.93); }

/* Web trên điện thoại đeo luôn thanh này — vào bằng trình duyệt hay bằng icon
   ngoài màn hình chính thì thao tác như nhau. Màn hình rộng thì thôi, ở đó đã
   có nav trên đầu và chân trang bốn cột. */
@media (min-width: 761px) { body:not(.la-app) .app-chan { display: none; } }
@media (max-width: 760px) {
  body:not(.la-app) { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }
}

/* --- Giao dien moi: thanh day dang vien thuoc noi (floating pill) ----------
   Ban cu sat day, 5 o chia deu, nut giua nho len bang vien tron. Nhin chat
   nhung nang mat khi cuon. Ban moi gom vao mot vien nam giua day, cach mep
   12px, bo vien va bong mo, nut giua gon hon (khong in so duoi nut). Van du
   5 thao tac: Trang chu / Tra cuu / Goi-Zalo / Gui anh / Chi duong-Quy trinh.
   Chi duong van do de nhan ra tren pil trang mo. */
.app-chan.app-chan-moi {
  left: 50%; right: auto; transform: translateX(-50%);
  bottom: max(10px, env(safe-area-inset-bottom, 0px));
  width: calc(100% - 24px); max-width: 460px;
  border: 1px solid rgba(0,0,0,.08);
  border-radius: 999px;
  background: rgba(255,255,255,.92);
  -webkit-backdrop-filter: saturate(1.2) blur(14px);
  backdrop-filter: saturate(1.2) blur(14px);
  box-shadow: 0 8px 28px rgba(15,23,42,.16), 0 1px 3px rgba(15,23,42,.08);
  padding: 6px 8px;
  padding-bottom: 6px;
  gap: 2px;
  justify-content: space-around;
}
.app-chan.app-chan-moi a {
  padding: 7px 6px 6px; border-radius: 999px; font-size: 10px; gap: 2px;
}
.app-chan.app-chan-moi a:active { background: rgba(15,23,42,.06); }
.app-chan.app-chan-moi a.dang { background: var(--th-nen); color: var(--muc); }
.app-chan.app-chan-moi .bt { width: 20px; height: 20px; }
.app-chan.app-chan-moi .app-chan-tron .tron {
  width: 48px; height: 48px; margin: 0;
  border-width: 3px; box-shadow: 0 4px 12px rgba(0,0,0,.18);
}
.app-chan.app-chan-moi .app-chan-tron .tron .bt { width: 22px; height: 22px; }
.app-chan.app-chan-moi a.app-chan-tron { flex-grow: 0; padding: 2px; background: transparent; }
.app-chan.app-chan-moi .app-lh-menu {
  bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%);
  border-radius: 14px;
}
/* Khi bat gd_moi, body van chua 76px cho thanh sat day — pil noi chi can ~72px */
body:has(.app-chan-moi) { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
body.la-app:has(.app-chan-moi) { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
@media (min-width: 761px) { body:not(.la-app) .app-chan.app-chan-moi { display: none; } }
body.la-app.man-1 .app-chan.app-chan-moi { position: fixed; }

/* --- Thẻ mời cài, nổi giữa màn hình ------------------------------------ */
.moi-nen {
  position: fixed; inset: 0; z-index: 59;
  background: rgba(8, 12, 18, .38);
  animation: moi-mo .2s ease both;
}
.moi-cai {
  position: fixed; z-index: 60;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(340px, calc(100vw - 40px));
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 8px; padding: 22px 20px 14px;
  background: var(--the); border: 1px solid var(--vien-dam);
  border-radius: 18px; box-shadow: var(--bong-cao);
  animation: moi-len .26s cubic-bezier(.34, 1.4, .64, 1) both;
}
@keyframes moi-mo { from { opacity: 0; } to { opacity: 1; } }
@keyframes moi-len {
  from { opacity: 0; transform: translate(-50%, -46%) scale(.94); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .moi-cai,
.moi-nen { animation: none; } }
/* Chốt chặn thứ hai, không dính gì tới JavaScript: màn hình rộng thì thẻ mời
   cài không có cửa hiện, kể cả khi đoạn script trên kia tính sai. Lời mời chỉ
   dành cho máy cầm tay. */
@media (min-width: 1025px) { .moi-cai,
.moi-nen { display: none !important; } }

.moi-anh { display: flex; }
/* Chỉ nhắm vào dấu hiệu, không nhắm "mọi svg trong .moi-anh": bên trong nó
   giờ còn thẻ chữ T-PIC, ép cỡ cứng lên chữ là kéo méo. Và chỉ đặt height:
   khung dấu hiệu đã cắt sát mực nên không còn vuông. */
.moi-anh .logo-dau, .moi-anh .logo-4d { height: 54px; width: auto; }
.moi-anh .chu-tpic { height: 15px; width: auto; }
.moi-cai b { font-size: 18px; line-height: 1.25; letter-spacing: -.01em; }
.moi-cai > span { font-size: 13px; color: var(--muc-mo); line-height: 1.45; }
.moi-cai .moi-nut {
  width: 100%; margin-top: 6px; padding: 15px 18px;
  font-size: 16px; min-height: 52px;
}
.moi-sau {
  background: none; border: none; cursor: pointer; padding: 5px 10px;
  font-size: 13px; color: var(--muc-mo); text-decoration: underline;
}
.moi-sau:hover { color: var(--muc); }
.moi-dong {
  position: absolute; top: 5px; right: 7px;
  width: 32px; height: 32px; padding: 0; line-height: 1;
  font-size: 22px; background: none; border: none; cursor: pointer; color: var(--muc-mo);
}
.moi-dong:hover { color: var(--muc); }

/* Hai bước của iPhone. Vẽ đúng biểu tượng Chia sẻ vì khách phải nhận ra nó
   trên thanh dưới của Safari, không phải đoán từ chữ. */
.moi-ios { width: 100%; margin-top: 2px; display: flex; flex-direction: column; gap: 9px; }
.moi-ios p {
  margin: 0; display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; line-height: 1.35; text-align: left;
}
.moi-so {
  flex: none; width: 21px; height: 21px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font: 700 11px/1 "Roboto Mono", ui-monospace, monospace;
  background: var(--sang); color: var(--tren-sang);
}
.moi-ios-bt {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: var(--th-nen); color: var(--th);
}
.moi-ios-bt .bt { width: 17px; height: 17px; }
.moi-mui {
  font-size: 20px; line-height: 1; color: var(--muc-mo);
  animation: moi-nhun 1.4s ease-in-out infinite;
}
@keyframes moi-nhun { 0%,
100% { transform: translateY(0); } 50% { transform: translateY(5px); } }
@media (prefers-reduced-motion: reduce) { .moi-mui { animation: none; } }

/* --- Hai khối dưới lưới app: làm thế nào, và gọi ai --------------------- */
.app-muc {
  margin-top: 22px; padding: 16px 15px 17px;
  background: var(--the); border: 1px solid var(--vien); border-radius: var(--r);
}
.app-h2 { margin: 0 0 12px; font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.app-gap:first-of-type { margin-top: 22px; }

/* --- Khối gấp ở màn hình đầu -------------------------------------------
   Cùng cái vỏ thẻ như .app-muc, nhưng đóng lại chỉ còn một dòng cao 50px —
   đủ để đọc tên khối và bấm bằng ngón cái. Ba khối đóng lại tốn 170px thay
   vì hơn chín trăm, nhờ đó cả màn hình chính lọt vào một lần nhìn. */
.app-gap {
  margin-top: 10px;
  background: var(--the); border: 1px solid var(--vien); border-radius: var(--r);
}
.app-gap > summary {
  display: flex; align-items: center; gap: 11px;
  min-height: 50px; padding: 12px 14px; box-sizing: border-box;
  cursor: pointer; color: var(--muc);
  font-size: 14.5px; font-weight: 650; letter-spacing: -.01em;
  /* Hai dòng: bỏ tam giác mặc định của Chrome/Safari và của Firefox. */
  list-style: none;
}
.app-gap > summary::-webkit-details-marker { display: none; }
.app-gap > summary::marker { content: ""; }
.app-gap > summary:active { background: var(--th-nen); border-radius: var(--r); }
.app-gap > summary:focus-visible { outline: 2px solid var(--sang); outline-offset: -3px; }
.app-gap[open] > summary { border-bottom: 1px solid var(--vien); border-radius: 0; }
.app-gap-bt { flex: none; display: flex; color: var(--sang-muc); }
.app-gap-bt .bt { width: 20px; height: 20px; }
.app-gap-ten { flex: 1 1 auto; min-width: 0; }
.app-gap-mui { flex: none; display: flex; color: var(--muc-mo); transition: transform .18s ease; }
.app-gap-mui .bt { width: 18px; height: 18px; }
.app-gap[open] .app-gap-mui { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .app-gap-mui { transition: none; } }
.app-gap-than { padding: 13px 14px 15px; }
.app-gap-than > :first-child { margin-top: 0; }

.app-buoc { margin: 0; padding: 0; list-style: none; counter-reset: b; }
.app-buoc li {
  position: relative; counter-increment: b;
  padding: 0 0 14px 34px; display: flex; flex-direction: column; gap: 2px;
}
.app-buoc li:last-child { padding-bottom: 2px; }
.app-buoc li::before {
  content: counter(b); position: absolute; left: 0; top: 0;
  width: 23px; height: 23px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font: 700 12px/1 "Roboto Mono", ui-monospace, monospace;
  background: var(--sang); color: var(--tren-sang);
}
/* Vạch nối các bước: đọc ra ngay là ba việc nối nhau, không phải ba gạch đầu
   dòng rời rạc. */
.app-buoc li:not(:last-child)::after {
  content: ""; position: absolute; left: 11px; top: 27px; bottom: 6px;
  width: 1px; background: var(--vien-dam);
}
.app-buoc b { font-size: 14px; font-weight: 650; line-height: 1.3; }
.app-buoc span { font-size: 12.5px; color: var(--muc-mo); line-height: 1.45; }

.app-nut-hang { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 15px; }
.app-nut-hang .nut { flex: 1 1 auto; text-align: center; padding: 11px 14px; font-size: 13.5px; }

/* Số điện thoại: to bằng ngón tay, bấm là gọi. Đây là thứ khách mở app ra
   tìm nhiều nhất sau danh sách việc. */
.app-so {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 13px 14px; border-radius: var(--r);
  background: var(--th-nen); color: var(--th); text-decoration: none;
  font: 700 20px/1 "Roboto Mono", ui-monospace, monospace; letter-spacing: .01em;
}
.app-so:active { filter: brightness(.96); }
.app-so .bt { width: 20px; height: 20px; stroke-width: 1.8; }

.app-lh-hang { display: flex; flex-wrap: wrap; gap: 9px; margin-top: 10px; }
.app-lh-hang .nut { flex: 1 1 auto; text-align: center; padding: 10px 14px; font-size: 13px; }

.app-lh-ds { margin: 14px 0 0; display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; }
.app-lh-ds dt { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muc-mo); padding-top: 2px; }
.app-lh-ds dd { margin: 0; font-size: 13.5px; line-height: 1.4; }

/* Hai ô tra đơn nằm cạnh nhau. Mã đơn dài hơn số điện thoại nên chia
   1.5/1 — chia đôi đều thì ô mã hết chỗ ngay trên máy 360px. */
.app-tra-doi { display: grid; grid-template-columns: 1.5fr 1fr; gap: 10px; margin-top: 13px; }
.app-tra-doi label { display: block; margin: 0; font-size: 13px; }
.app-tra-doi input {
  width: 100%; box-sizing: border-box; margin-top: 5px;
  /* 16px chẵn: nhỏ hơn là Safari trên iPhone tự phóng to cả trang lúc
     con trỏ nhảy vào ô, rồi để nguyên như thế. */
  padding: 12px 13px; font-size: 16px;
}
#tra-don .app-nut-to { margin-top: 13px; }

/* --- Màn hình con của app: tra đơn, gửi ảnh, quy trình -------------------
   Ba trang này đều đã có bản web. Bản app không phải bản web thu nhỏ: ô nhập
   to bằng ngón cái, xếp một cột, và thêm mấy thứ chỉ có nghĩa khi cầm điện
   thoại — nhớ đơn vừa tra, gấp bớt ô không bắt buộc, mở thẳng camera. */

.app-dau-2 { justify-content: flex-start; gap: 4px; }
.app-lui {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; margin-left: -10px; border-radius: 50%;
  color: var(--muc); text-decoration: none;
}
.app-lui:active { background: var(--th-nen); }
.app-lui .bt { width: 21px; height: 21px; stroke-width: 2; }
.app-tieu { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }

/* Ô nhập cỡ ngón tay. 16px không phải cho to đẹp: dưới 16px là Safari tự
   phóng cả trang lên lúc khách chạm vào ô, rồi để nguyên đấy — khách gõ xong
   không thấy cái nút gửi đâu nữa. */
.app-form { margin: 2px 0 20px; }
.app-form label { margin-bottom: 14px; font-size: 13.5px; }
.app-form input,
.app-form textarea { margin-top: 5px; padding: 13px 14px; font-size: 16px; }
.app-form textarea { min-height: 96px; }
.app-nut-to { width: 100%; padding: 15px 18px; font-size: 16px; min-height: 52px; }
/* Cùng lớp ấy đặt lên thẻ <a>: thẻ a không có kiểu nút sẵn nên phải tự căn
   giữa chữ, còn <button> thì trình duyệt lo hộ. */
a.app-nut-to { display: flex; align-items: center; justify-content: center; box-sizing: border-box; }
.app-nut-hang-doc { flex-direction: column; }

/* Hai lối nạp ảnh ở màn gửi ảnh: chụp ngay, hoặc lấy tấm đã có trong máy.
   Ô input thật nấp sau nhãn — giấu bằng display:none thì bàn phím Tab không
   tới được nữa, nên đẩy ra khỏi tầm nhìn mà vẫn để nó tồn tại. */
.tep-an {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.app-tep { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 6px 0 4px; }
.app-tep-nut {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 16px 10px; text-align: center; cursor: pointer;
  border: 1px solid var(--vien-dam); border-radius: var(--r);
  background: var(--the); color: var(--muc);
}
.app-tep-nut .bt { width: 26px; height: 26px; color: var(--sang-muc); }
.app-tep-nut b { font-size: 14px; font-weight: 650; }
.app-tep-nut span { font-size: 11.5px; color: var(--muc-mo); line-height: 1.35; }
.app-tep-nut:active { background: var(--th-nen); }
/* Ô input nấp sau nhãn nên vòng focus phải mượn nhãn mà hiện, không thì người
   dùng bàn phím Tab tới đây là mất dấu con trỏ. */
.tep-an:focus-visible + .app-tep-nut,
.app-tep-nut:focus-visible { outline: 2px solid var(--muc); outline-offset: 2px; }
.app-nhan { display: block; font-weight: 650; font-size: 14px; margin-top: 4px; }

/* Màn hình một dịch vụ. Tên việc đứng cạnh đúng cái biểu tượng khách vừa bấm
   ngoài lưới trang chủ. */
.app-dv-dau { display: flex; align-items: center; gap: 13px; margin: 2px 2px 14px; }
.app-dv-bt { flex: none; display: flex; color: var(--sang-muc); }
.app-dv-bt .bt { width: 40px; height: 40px; }
.app-dv-bt .btm { width: 46px; height: 46px; }
.app-dv-ten { margin: 0 0 5px; font-size: 21px; line-height: 1.2; letter-spacing: -.02em; }
/* Ba con số: mấy ngày, bảo hành mấy tháng, cân sai lệch bao nhiêu. */
.app-so3 {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 14px 0 4px;
}
.app-so3 > div {
  padding: 12px 6px; text-align: center;
  border: 1px solid var(--vien); border-radius: var(--r); background: var(--the);
}
.app-so3 b { display: block; font-size: 19px; line-height: 1.15; letter-spacing: -.02em; }
.app-so3 span { display: block; margin-top: 3px; font-size: 11px; color: var(--muc-mo); line-height: 1.3; }
.app-ds-so { margin: 0; padding-left: 20px; display: grid; gap: 10px; font-size: 13.5px; line-height: 1.55; }
.app-ds-so::marker,
.app-ds-so li::marker { color: var(--muc-mo); }

/* Thẻ đơn máy nhớ giùm, nằm trên cùng: mở app ra là đã thấy đường vào đơn
   cũ, không phải moi mã đơn trong tin nhắn. */
.app-luu { display: flex; align-items: center; gap: 4px; margin: 0 0 18px; }
.app-luu-mo {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 10px; text-align: left;
  padding: 12px 14px; border-radius: var(--r);
  background: var(--th-nen); color: var(--th); border: 1px solid var(--th-vien);
  font: 600 13.5px/1.3 Roboto, system-ui, sans-serif;
}
.app-luu-mo:hover { background: var(--th-nen); }
.app-luu-mo:active { filter: brightness(.96); }
.app-luu-mo .bt { flex: none; width: 19px; height: 19px; }
.app-luu-mo b {
  display: block; margin-top: 2px; overflow-wrap: anywhere;
  font: 500 12.5px/1.35 "Roboto Mono", ui-monospace, monospace;
}
.app-luu-quen {
  flex: none; padding: 12px 8px; background: none; color: var(--muc-mo);
  font-size: 12.5px; font-weight: 500; text-decoration: underline;
}
.app-luu-quen:hover { background: none; color: var(--muc); }

.app-kq { margin-top: 16px; }
.app-kq h3 { overflow-wrap: anywhere; }
.app-duoi { margin: 12px 2px 0; }

/* Gửi xong thì dẹp form, chỉ còn mã yêu cầu và hai đường đi tiếp. */
.app-xong { display: grid; justify-items: center; text-align: center; gap: 13px; padding: 20px 2px 6px; }
.app-xong-bt { color: var(--nhan); }
.app-xong-bt .bt { width: 46px; height: 46px; stroke-width: 1.7; }
.app-xong .bao { width: 100%; text-align: left; }
.app-xong .ma-yc { width: 100%; }
.app-xong p { margin: 0; }
.app-xong .app-nut-hang { width: 100%; margin-top: 2px; }

/* Nếp gấp cho mấy ô không bắt buộc ở màn gửi ảnh. */
.app-them { margin: -6px 0 16px; }
.app-them > summary {
  display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer;
  padding: 10px 2px; font-size: 13.5px; font-weight: 600; color: var(--th);
}
.app-them > summary::-webkit-details-marker { display: none; }
.app-them > summary::before {
  content: "+"; flex: none; width: 21px; height: 21px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--th-nen); font: 700 15px/1 ui-monospace, monospace;
}
.app-them[open] > summary::before { content: "–"; }   /* dán thẳng, xem ghi chú ở .app-xep */
.app-them-noi { padding-top: 4px; }

/* Quy trình gấp thành nếp: nhìn hết dàn bước trong một màn, cần đọc kỹ bước
   nào thì mở bước ấy. */
.app-xep { display: grid; gap: 8px; margin: 2px 0 4px; }
.app-xep details { background: var(--the); border: 1px solid var(--vien); border-radius: var(--r); }
.app-xep summary {
  display: flex; align-items: center; gap: 11px; list-style: none;
  padding: 13px 14px; cursor: pointer;
}
.app-xep summary::-webkit-details-marker { display: none; }
/* Nhan buoc lay thang tu noi dung Kendy go ("BƯỚC 1"), khong phai mot chu
   so. Ep vao vong tron 26px thi chu trang tran ra ngoai, doc khong duoc —
   cho no gian theo be ngang cua chu. */
.app-xep .n {
  flex: none; height: 22px; padding: 0 9px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  white-space: nowrap; letter-spacing: .06em;
  font: 700 11px/1 "Roboto Mono", ui-monospace, monospace;
  background: var(--sang); color: var(--tren-sang);
}
.app-xep summary b { font-size: 14.5px; font-weight: 650; line-height: 1.3; }
/* Mũi tên vẽ bằng hai cạnh viền, KHÔNG bằng ký tự.
   html/template nuốt escape CSS: viết content:"A" thì nó dịch  thành
   một ký tự điều khiển thật rồi để lại "A" — đó là cái ký hiệu lạ nằm ở đây
   suốt. Ký tự dán thẳng cũng sống được, nhưng hình học thì không phụ thuộc
   font nào có glyph ấy. */
.app-xep summary::after {
  content: ""; flex: none; margin-left: auto; margin-right: 4px;
  width: 8px; height: 8px;
  border-right: 2px solid var(--muc-mo); border-bottom: 2px solid var(--muc-mo);
  transform: translateY(-2px) rotate(45deg); transition: transform .18s ease;
}
.app-xep details[open] summary::after { transform: translateY(2px) rotate(-135deg); }
.app-xep p { margin: 0; padding: 0 15px 15px 15px; font-size: 13.5px; line-height: 1.55; color: var(--muc-mo); }

.app-muc p { margin: 0; font-size: 13.5px; line-height: 1.55; }
.app-muc h3 { font-size: 14.5px; }
.app-doi { display: grid; gap: 15px; }
.app-doi p { margin-top: 6px; }
@media (min-width: 560px) { .app-doi { grid-template-columns: 1fr 1fr; gap: 18px; } }

/* ==========================================================================
   MATERIAL 3 — THANG CHỮ VÀ LINH KIỆN
   --------------------------------------------------------------------------
   Khối này đứng CUỐI tệp là cố ý. Bố cục của bộ "Kem & nắng" đã được nhấc lên
   thành luật trần khi bỏ hệ giao diện, nên nó nằm ở dạng `body .nut` (0,1,1).
   Muốn đè phải bằng đặc hiệu đó, mà không nên đẩy đặc hiệu cao hơn nữa (càng
   cao càng khó sửa sau) — nên cùng dạng `body <thẻ>` rồi thắng bằng thứ tự.
   Chuyển khối này lên trên là mất tác dụng.

   Cái gì theo M3 và cái gì giữ của bộ kem:
     THEO M3  — thang chữ, hình và cỡ nút, lớp trạng thái khi chạm, bo góc,
                ô nhập, chip, thanh trên, thanh dưới, gợn sóng.
     GIỮ KEM  — bố cục trang: khung 1296px, hero hai cột, nhịp khối. Đó là
                thứ Kendy chốt giữ nguyên.
   ========================================================================== */
:root {
  /* Thang chữ M3. Cặp số là cỡ/dòng, đơn vị px. */
  --md-display-l:  700 57px/64px Roboto, system-ui, sans-serif;
  --md-headline-l: 700 32px/40px Roboto, system-ui, sans-serif;
  --md-title-l:    500 22px/28px Roboto, system-ui, sans-serif;
  --md-title-m:    500 16px/24px Roboto, system-ui, sans-serif;
  --md-body-l:     400 16px/24px Roboto, system-ui, sans-serif;
  --md-body-m:     400 14px/20px Roboto, system-ui, sans-serif;
  --md-label-l:    500 14px/20px Roboto, system-ui, sans-serif;
  --md-label-m:    500 12px/16px Roboto, system-ui, sans-serif;
}

/* --- Icon Material Symbols ------------------------------------------------
   Bản nhúng là bản cắt theo tên, chỉ có 36 icon. Viết tên icon không nằm
   trong danh sách đó thì ra ô trống chứ không ra icon mặc định — thêm icon
   là phải tải lại font (scratchpad/font.py giữ danh sách).

   Tám icon dịch vụ tự vẽ (btm-* trong hinh.html) KHÔNG đổi sang Material
   Symbols: bộ này không có hình cho dán viền, phủ nhám, vá mặt. */
.msym {
  font-family: 'Material Symbols Outlined';
  font-weight: 400; font-style: normal; font-size: 24px;
  line-height: 1; letter-spacing: normal; text-transform: none;
  display: inline-block; white-space: nowrap; direction: ltr;
  -webkit-font-feature-settings: 'liga'; font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased; vertical-align: middle;
  user-select: none; flex: none;
}
.msym-nho { font-size: 20px; }
.msym-to  { font-size: 40px; }

/* --- Lớp trạng thái ------------------------------------------------------
   M3 không đổi màu nền khi rê chuột; nó phủ một lớp màu-chữ mờ lên trên. Nhờ
   vậy một luật dùng được cho mọi nút bất kể nền màu gì, và nút màu nhấn không
   bị nhạt dần vào nền trang như cách pha màu cũ. Độ mờ theo chuẩn: 8% khi rê,
   10% khi đang nhấn. */
body .nut,
body .nut-nho,
body .m3-lop { position: relative; overflow: hidden; isolation: isolate; }
body .nut::before,
body .nut-nho::before,
body .m3-lop::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: currentColor; opacity: 0; transition: opacity .12s linear;
  pointer-events: none;
}
body .nut:hover::before,
body .nut-nho:hover::before,
body .m3-lop:hover::before { opacity: .08; }
body .nut:active::before,
body .nut-nho:active::before,
body .m3-lop:active::before { opacity: .10; }

/* --- Nút ------------------------------------------------------------------
   Cao 40, bo tròn hết, chữ label-large. Nút chính tô ô-liu đặc, chữ trắng —
   6.49:1. Trước đây tô volt, và đó là chỗ đo thiếu: volt với chữ ô-liu đúng
   là 13.3:1 nên CHỮ đọc tốt, nhưng bản thân cái nút chỉ hơn mặt thẻ 1.05:1,
   tức mắt không thấy MÉP nút ở đâu. Chữ rõ mà nút vô hình. Volt lui về đúng
   chỗ nó thắng: nền tối (--sang-tren-toi). */
body .nut {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 24px; border-radius: 999px;
  font: var(--md-label-l); letter-spacing: .1px;
  border: 1px solid transparent; text-decoration: none;
  transition: box-shadow .15s ease;
}
body .nut-chinh {
  background: var(--md-primary-container); color: var(--md-on-primary-container);
  box-shadow: none;
}
body .nut-chinh:hover { background: var(--md-primary-container); box-shadow: var(--md-elev-1); }
body .nut-vien {
  background: transparent; color: var(--md-primary);
  border-color: var(--md-outline);
}
body .nut-vien:hover { background: transparent; border-color: var(--md-outline); color: var(--md-primary); }
/* Nút đặt trên tấm tối của hero: viền và chữ phải sáng lên; phần rê chuột thì
   lớp trạng thái tự lo vì nó lấy theo currentColor. */
body .hero .nut-vien { border-color: rgba(255,255,255,.42); color: #fff; background: transparent; }
body .hero .nut-vien:hover { border-color: rgba(255,255,255,.42); color: #fff; background: transparent; }
body .hero .the .nut-vien { border-color: var(--md-outline); color: var(--md-primary); }
body .hero .nut-chinh,
body .hero .nut-chinh:hover { background: var(--sang-tren-toi); color: var(--tren-sang-toi); }
/* Nút gọi hành động ở hero to hơn một bậc — M3 cho phép cỡ lớn ở chỗ quan
   trọng nhất trang. */
body .hero-nut .nut { min-height: 56px; padding: 0 32px; font: var(--md-title-m); }
body .nut-nho {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 16px; border-radius: 999px;
  font: var(--md-label-l); box-shadow: none;
}

/* --- Thẻ ------------------------------------------------------------------
   M3 có ba dạng thẻ; dùng dạng viền (outlined) vì nền trang và nền thẻ ở đây
   chênh nhau rất ít — bỏ viền là thẻ tan vào trang. Bo 12px theo thang M3. */
body .the {
  background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline-variant);
  border-radius: 12px; box-shadow: none;
}

/* Ô "bốn bước" cũng là thẻ, nhưng nó không mang class .the nên bị bỏ lại ở
   luật bộ kem: css.html:1983 cho mọi ô nền --nen-2, css.html:2143 tô riêng ô
   CHẴN bằng --th-nen. Mà --nen-2 (--kem-2 #CDC9DE) trùng đúng màu nền trang
   (--kem #CDC9DE) — nên ô lẻ tan vào trang, chỉ ô chẵn nổi lên, nhìn như
   trang hỏng. Kéo cả lưới về đúng một dáng thẻ viền như .the; nth-child viết
   lại để đè luật tô luân phiên kia. */
body .buoc > div,
body .buoc > div:nth-child(2n) {
  background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline-variant);
  border-radius: 12px; box-shadow: none;
}

/* --- Chip -----------------------------------------------------------------
   Giữ chữ mono viết hoa: đây là nhãn kỹ thuật đọc lướt (mã đơn, trạng thái),
   không phải chip lọc của M3. Chỉ lấy hình chip M3 — bo 8px và chiều cao đủ
   chạm — chứ không lấy thang chữ. */
body .chip {
  display: inline-flex; align-items: center; min-height: 24px;
  padding: 0 8px; border-radius: 8px;
}

/* --- Ô nhập ---------------------------------------------------------------
   Dạng outlined của M3: viền 1px outline, bo 4px, cao 56, chữ body-large;
   lúc có tiêu điểm thì viền dày 2px màu primary (bù padding để chữ không nhảy).

   KHÔNG làm nhãn nổi (nhãn chạy lên đè trên viền khi gõ). Nhãn nổi cần nhãn
   đứng SAU ô trong DOM để CSS bắt được :placeholder-shown, mà ở đây khoảng ba
   mươi biểu mẫu đang viết <label>Tên<input></label>. Đổi hết chỉ để lấy hiệu
   ứng nhãn chạy là đánh đổi sai: rủi ro trải trên ba mươi tệp, cái được là một
   hiệu ứng. Nhãn vẫn nằm trên ô, đúng vai và vẫn đọc được. */
body input,
body textarea,
body select {
  min-height: 56px; padding: 16px; border-radius: 4px;
  border: 1px solid var(--md-outline);
  background: var(--md-surface); color: var(--md-on-surface);
  font: var(--md-body-l);
}
body textarea { min-height: 96px; line-height: 24px; }
body select { padding-block: 0; }
body input[type=checkbox],
body input[type=radio] { min-height: 0; padding: 0; accent-color: var(--md-primary); }
body input[type=file] { min-height: 0; padding: 12px; border-style: dashed; }
body input:hover,
body textarea:hover,
body select:hover { border-color: var(--md-on-surface); }
body input:focus,
body textarea:focus,
body select:focus {
  outline: none; border: 2px solid var(--md-primary); padding: 15px;
  box-shadow: none;
}
body select:focus { padding-block: 0; }

/* --- Thang chữ áp cho thân trang -----------------------------------------
   Body theo body-large của M3: 16/24. Trước dòng cao 1.68 — thoáng hơn, nhưng
   thang M3 tính nhịp dọc theo bội số 4 của dòng 24; lệch một chỗ là lệch cả
   thang. */
body { font: var(--md-body-l); }
/* Bài viết là chỗ người ta đọc liền hơn nghìn chữ chứ không lướt. Dòng 24px ở
   đó đọc chật; nới lên 28 mà vẫn là bội số của 4 nên không phá nhịp dọc. */
body .bai p,
body .bai li { font-size: 16px; line-height: 28px; }
body .nho { font: var(--md-body-m); }

/* ==========================================================================
   MÀN HÌNH ĐẦU CỦA APP — bản dựng lại
   --------------------------------------------------------------------------
   Đứng sau khối linh kiện M3 vì nó đè lên một số luật ở trên: cùng đặc hiệu
   thì luật viết sau thắng.

   Mọi luật ở đây đều mở đầu bằng `body.la-app`. Không phải cho đều mắt: luật
   nền của trang web là dạng `body h2` / `body section`, viết class trần là
   thua, và thua im lặng. Tiêu đề khối giá mà để `.app-muc-ten` trần thì nó ăn
   `body h2 { font-size: clamp(24px,3vw,36px) }` — ra chữ 24px giữa màn hình
   điện thoại.

   Bốn thứ đổi so với bản trước, theo đúng thứ tự Kendy chỉ ra:
     1. Băng ảnh tràn hết bề ngang, không chừa lề hai bên.
     2. Lề và khoảng cách giữa các khối bóp lại — bản trước một màn hình chỉ
        chứa được lưới việc, giá và cam kết đều nằm dưới nếp gấp.
     3. Nền chuyển sắc theo tông quả bóng pickleball thay cho một mảng màu
        phẳng.
     4. Icon và logo có khối: nền chuyển sắc, vạch sáng ở mép trên, bóng đổ
        bên dưới. Đây là chỗ CỐ Ý đi khác Material 3 — M3 vẽ phẳng, phân tầng
        bằng màu nền chứ không bằng bóng đổ. Trên màn 6 inch cầm tay, phẳng
        hoàn toàn thì tám ô dịch vụ dính thành một mảng. Phần còn lại của app
        — thang chữ, nút, ô nhập, thanh dưới — vẫn M3 nguyên.
   ========================================================================== */

/* Nền: chuyển sắc từ volt rất nhạt trên đỉnh xuống trắng ngà. Gắn theo khung
   nhìn (fixed) nên cuộn tới đâu cũng không lộ chỗ nối màu. */
body.la-app {
  background:
    radial-gradient(125% 52% at 50% -8%, rgba(255, 199, 44, .24) 0%, rgba(255, 199, 44, 0) 62%),
    linear-gradient(178deg, #B3AECB 0%, #C3BFD7 38%, var(--md-surface) 100%);
  background-attachment: fixed;
}

/* Lề chung của thân app, để thành biến vì băng ảnh phải trừ đúng số này ra
   mới tràn được hết bề ngang. */
/* Lề ngang của cả màn app. Khai ở body chứ không ở .app-than: bảng hiệu nằm
   NGOÀI .app-than, mà địa chỉ góc phải phải thẳng hàng với mép banner bên
   dưới. Hai con số 14px gõ tay ở hai chỗ thì sớm muộn một chỗ bị sửa lẻ. */
body.la-app { --app-le: 14px; }
body.la-app .app-than {
  max-width: 620px; margin: 0 auto; padding: 10px var(--app-le) 6px;
}
body.la-app .app-than section.app-muc {
  margin-top: 12px; padding: 12px 12px 14px;
  background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline-variant); border-radius: 16px;
}

/* --- Bảng hiệu ------------------------------------------------------------
   Xếp ngang, không xếp giữa. Bản trước logo nằm giữa, tên trạm 29px, dòng
   nghề bên dưới — hết gần trăm rưỡi điểm ảnh cho thứ khách đã biết rồi, đẩy
   băng ảnh xuống quá nếp gấp. */
body.la-app .app-bia {
  text-align: left; border-bottom: none; background: transparent;
  padding: calc(12px + env(safe-area-inset-top, 0px)) var(--app-le) 10px;
}
body.la-app .app-bia .app-bia-lk { display: flex; align-items: center; gap: 11px; }
body.la-app .app-bia .logo-dau,
body.la-app .app-bia .logo-4d {
  height: 42px; width: auto; margin: 0; flex: none;
  /* Bóng bám theo hình thật trong SVG chứ không theo khung chữ nhật. */
  filter: drop-shadow(0 2px 3px rgba(46, 42, 94, .22));
}
body.la-app .app-bia .logo-khoi { margin: 0; gap: 2px; }
body.la-app .app-bia .chu-tpic { height: 12px; }
body.la-app .app-bia-chu { display: grid; min-width: 0; }
body.la-app .app-bia-ten {
  margin-top: 0; font: 700 19px/1.15 Roboto, system-ui, sans-serif;
  letter-spacing: -.02em;
}
/* Viên nhãn "Nhận sửa vợt toàn quốc", bên phải tên trạm.

   ĐẢO MÀU chứ không phải chữ màu trên nền trang: bản đầu là chữ vàng đặt
   trong banner, mà nét vẽ vợt ở đấy cũng vàng nên chữ lẫn vào hình, nhìn
   không ra. Nền lime đặc + chữ tối đo được 9.7:1 và không phụ thuộc vào thứ
   nằm dưới nữa. Ở bảng hiệu nền sáng thì chính mảng lime là cái đập vào mắt
   trước, đúng việc của một cái nhãn.

   Không viết hoa toàn bộ, không giãn ký tự: "NHẬN SỬA VỢT TOÀN QUỐC" giãn
   .09em rộng thêm chừng 30px, trên máy 360px thì viên nhãn phải cắt ba chấm
   giữa chữ "TOÀN". Chữ thường vẫn đủ to để đọc mà vừa chỗ.

   flex: 0 1 auto + min-width: 0 — bảng hiệu còn có khối mạng xã hội 2×2 bên
   phải khi Kendy điền link ở /qt/lien-he. Chật thì nhãn co lại và cắt ba
   chấm, chứ không đẩy khối kia ra khỏi mép. */
body.la-app .app-bia-nhan {
  flex: 0 1 auto; min-width: 0;
  font: 700 clamp(10px, 2.9vw, 11.5px)/1.25 Roboto, system-ui, sans-serif;
  color: #1E1A3C; background: var(--lime);
  border-radius: 999px; padding: 5px 10px;
  box-shadow: 0 2px 6px -2px rgba(46, 42, 94, .38);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- Dải địa chỉ, ngay dưới bảng hiệu -------------------------------------
   Bản trước nhét khối này vào góc phải bảng hiệu cho khỏi tốn chiều cao. Sai:
   nó ăn 48% bề ngang, cột trái còn chưa đầy 160px nên tên trạm lẫn dòng mô tả
   cùng bị cắt cụt. Tiết kiệm được 26px chiều cao mà hỏng ba dòng chữ thì
   không phải tiết kiệm.

   Xuống đây thành một dải riêng, mỗi thứ được cả chiều ngang. Và chiều cao
   ấy KHÔNG mất đi đâu cả: banner ngay dưới là phần co giãn duy nhất trong
   thân (flex:1), nó nhả ra đúng phần dải này chiếm — nên /app vẫn gói trong
   một màn không cuộn, chỉ hình nhỏ đi vài chục điểm ảnh.

   Ba phần trên một hàng: ghim — địa chỉ — nhãn "CHỈ ĐƯỜNG".
     - Địa chỉ nhận flex:1 + min-width:0 nên nó là thứ co lại và cắt đuôi bằng
       ellipsis khi chật. Ghim và nhãn flex:none: hai cái ấy nói "bấm vào đây
       ra bản đồ", cắt mất là dải mất luôn nghĩa.
     - Nhãn nằm bên PHẢI như nút chứ không nằm trên như tiêu đề: dải chỉ cao
       một dòng, xếp dọc là quay lại hai dòng và ăn thêm chiều cao.
   Dùng cặp tertiary-container: có sẵn ở cả hai bảng màu (kem-vàng ở bảng tím,
   bạc hà ở bảng volt cũ) nên không phải bịa mã màu mới, và cả hai đều ăn được
   mực --forest. */
body.la-app .app-bia { display: flex; align-items: center; gap: 10px; }
body.la-app .app-bia .app-bia-lk { flex: 1; min-width: 0; }
body.la-app .app-cho {
  display: flex; align-items: center; gap: 8px;
  text-decoration: none;
  background: var(--md-tertiary-container);
  color: var(--md-on-tertiary-container);
  border-radius: 12px; padding: 7px 11px;
}
/* Nét mảnh hơn mặc định: ở cỡ 18px thì stroke 1.6 làm cái ghim đặc lại thành
   một vệt. */
body.la-app .app-cho > .bt {
  width: 18px; height: 18px; flex: none; stroke-width: 1.5;
  color: var(--md-error);
}
/* Xuống dòng chứ không cắt đuôi bằng "…": địa chỉ Hà Nội đủ số nhà, phường,
   quận thì dài 45-55 ký tự, một hàng ngang không bao giờ chứa nổi — mà cắt
   mất đúng cái quận là khách không biết trạm ở đâu, tức là dải này mất luôn
   lý do tồn tại. Hai dòng là hết: dòng thứ ba thì đây không còn là một dải
   phụ nữa. Chiều cao thêm ra banner nhả cho, xem chú thích trên. */
body.la-app .app-cho-chu {
  flex: 1; min-width: 0;
  font: 500 12.5px/1.32 Roboto, system-ui, sans-serif;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
/* Ghim và nhãn "CHỈ ĐƯỜNG" dùng --md-error: đỏ là màu ai cũng đọc ngay ra
   "vị trí trên bản đồ", và nó là mã màu duy nhất trong hệ không đổi theo bảng
   màu, nên dải đỏ y hệt ở cả bảng tím lẫn bảng volt cũ.
   Không hạ opacity: đỏ pha loãng trên nền kem ra hồng nhạt, trông như chữ bị
   vô hiệu hoá. Cỡ 10px cạnh địa chỉ 12.5px đã đủ giữ nhãn ở vai phụ. */
body.la-app .app-cho-nhan {
  flex: none;
  font: 600 10px/1 Roboto, system-ui, sans-serif;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--md-error);
}
/* Bấm vào có phản hồi: đây là link mở app khác (bản đồ), không có trạng thái
   :hover trên điện thoại nên chỉ còn lúc chạm để báo là đã nhận. Lún xuống
   chứ không mờ đi: dải đã có nền, giảm opacity là cả nền lẫn chữ nhạt cùng
   lúc trông như bị vô hiệu hoá. */
/* Bản app của dải báo. Bóp lại còn ~60% chiều cao bản web: ở đây nó ăn vào
   phần co giãn của banner, mà banner dưới 44px thì bản vẽ vợt chỉ còn một vệt.
   Chữ 10.5–12px vẫn đọc được vì nền lime đặc cho tương phản cao hơn hẳn chữ
   cùng cỡ đặt trên nền kem nhạt như bản trước. Viền trái mỏng hơn bản web
   (3px) cho cân với chiều cao đã bóp lại. */
body.la-app .tb-chuamo {
  margin: 6px 0 0; padding: 7px 11px; border-radius: 12px;
  border-left-width: 3px;
  font: 500 clamp(10.5px, 1.45svh, 12px)/1.38 Roboto, system-ui, sans-serif;
}
body.la-app .app-cho:active {
  transform: scale(.99); filter: brightness(.94);
}

/* Mạng xã hội trong bảng hiệu app. Hai cột auto: một trang thì ra một ô, bốn
   trang thì ra vuông 2×2 — không bao giờ thành hàng dài bốn cái đẩy tên trạm
   ra khỏi chỗ.

   flex: none để nó không co lại khi tên trạm dài; khối logo bên trái mới là
   thứ được phép nhường chỗ. */
body.la-app .app-bia-mxh {
  flex: none; display: grid; grid-template-columns: repeat(2, auto); gap: 2px;
}
body.la-app .app-bia-mxh a {
  display: grid; place-items: center; width: 23px; height: 23px;
  border-radius: 7px; color: var(--muc);
}
body.la-app .app-bia-mxh .bt { width: 15px; height: 15px; }
body.la-app .app-bia-mxh a:active { background: var(--md-surface-variant); }

/* --- Băng ảnh việc thật ---------------------------------------------------
   Tràn hết bề ngang bằng cách ăn ngược lề của .app-than. Cuộn ngang có điểm
   dừng nên vuốt một cái là đúng một tấm, không dừng lưng chừng giữa hai ảnh.

   overscroll-behavior-x: contain chặn cử chỉ "vuốt để lùi trang" của trình
   duyệt lúc vuốt hết tấm cuối — thiếu dòng này thì khách xem tới ảnh cuối rồi
   vuốt thêm một cái là văng ra khỏi app. */
body.la-app .app-bang {
  display: flex; gap: 8px; margin: 0 calc(-1 * var(--app-le)) 14px;
  padding: 0 var(--app-le); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none;
}
body.la-app .app-bang::-webkit-scrollbar { display: none; }
body.la-app .app-bang-o {
  flex: 0 0 calc(100% - 26px); margin: 0; position: relative;
  scroll-snap-align: center; border-radius: 16px; overflow: hidden;
  background: var(--md-surface-container);
  box-shadow: 0 8px 20px -10px rgba(46, 42, 94, .38), 0 1px 2px rgba(46, 42, 94, .12);
}
body.la-app .app-bang-o img {
  display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover;
}
/* Chú thích in đè lên ảnh, không đẩy khung cao thêm. Dải tối chỉ ở đáy, đủ để
   chữ trắng đọc được trên ảnh sáng. */
body.la-app .app-bang-o figcaption {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 20px 12px 9px;
  font: var(--md-label-l); color: #fff;
  background: linear-gradient(180deg, rgba(12, 14, 4, 0) 0%, rgba(12, 14, 4, .72) 100%);
}

/* --- Tiêu đề mục ----------------------------------------------------------
   Title-medium của M3, kèm một vạch volt ngắn bên trái. Vạch ấy thay cho cỡ
   chữ to: bốn mục nối nhau cần dấu phân đoạn, mà chữ to thì tốn chiều cao. */
body.la-app .app-muc-ten {
  display: flex; align-items: center; gap: 8px; margin: 0 0 10px;
  font: var(--md-title-m); letter-spacing: 0; color: var(--md-on-surface);
}
body.la-app .app-muc-ten::before {
  content: ""; width: 4px; height: 16px; border-radius: 2px; flex: none;
  background: linear-gradient(180deg, var(--green-2), var(--md-primary));
}

/* --- Ô việc trong lưới ----------------------------------------------------
   Khối nổi: nền chuyển sắc, một vạch sáng trong ở mép trên làm cạnh vát, hai
   tầng bóng bên dưới. Nhấn xuống thì lún — ô hạ 1px và bóng co lại.

   Có viền, dù đã có bóng. Trước đây để border:none và giao hết việc tách lớp
   cho bóng đổ; đo ra thẻ #FBFCF6 trên tấm trắng chỉ được 1.03:1, nghĩa là
   tám ô không có mép, chỉ có một vệt mờ dưới đáy. Bóng tả độ cao chứ không
   tả ranh giới — ranh giới phải là đường kẻ. */
body.la-app .app-luoi-nho { gap: 9px; max-width: 460px; }
body.la-app .app-o {
  align-items: center; text-align: center; gap: 8px;
  min-height: 0; padding: 12px 6px 11px; border-radius: 16px;
  border: 1px solid var(--vien);
  background: linear-gradient(163deg, var(--the) 0%, var(--kem-2) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 6px 14px -8px rgba(46, 42, 94, .40),
    0 1px 2px rgba(46, 42, 94, .10);
  transition: transform .13s ease, box-shadow .13s ease;
}
body.la-app .app-o:hover {
  border-color: var(--vien-dam);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 9px 18px -8px rgba(46, 42, 94, .46),
    0 1px 2px rgba(46, 42, 94, .12);
}
body.la-app .app-o:active {
  transform: translateY(1px) scale(.985);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 3px 8px -5px rgba(46, 42, 94, .40);
}
/* Việc nổi bật (tích ở /qt/dich-vu, bật/tắt cả cụm ở /qt/giao-dien).

   Vành vẽ bằng box-shadow inset chứ không tăng border-width: lưới này là
   grid-auto-rows 1fr ở màn hình đơn, một ô dày thêm 1px là cả hàng cao thêm
   1px, mà /app thì cấm cuộn.

   Ngôi sao đặt absolute, đè lên góc ô. Không chiếm dòng nào trong luồng nên
   ô nổi bật cao đúng bằng ô thường. */
body.la-app .app-o-noi {
  position: relative;
  border-color: var(--sang);
  box-shadow:
    inset 0 0 0 1px var(--sang),
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 6px 14px -8px rgba(46, 42, 94, .40),
    0 1px 2px rgba(46, 42, 94, .10);
}
body.la-app .app-o-noi:hover { border-color: var(--sang); }
body.la-app .app-o-sao {
  position: absolute; top: 4px; right: 4px; display: block;
  pointer-events: none;
}
/* Sao VÀNG nhận diện chứ không phải tím của chủ đề: nó phải nhảy ra khỏi ô
   trong một cái liếc. --lime vốn chỉ dành cho nền tối, đặt lên ô gần trắng
   thì nhoè mất, nên viền thêm một nét hổ phách --lime-dam. Nét 0.9 trên khung
   24, ở cỡ 13px là hơn nửa điểm ảnh: đủ tách hình khỏi nền mà không biến
   ngôi sao đặc thành hình vẽ nét. */
body.la-app .app-o-sao .bt {
  width: 13px; height: 13px;
  fill: var(--lime); stroke: var(--lime-dam); stroke-width: .9;
}

/* Ô "Việc khác" là lối thoát chứ không phải một việc — viền đứt để nó không
   đứng ngang hàng với tám việc thật. */
body.la-app .app-o-hoi {
  background: transparent; box-shadow: none;
  border: 1px dashed var(--md-outline-variant);
}
body.la-app .app-o-hoi:hover { box-shadow: none; border: 1px dashed var(--md-outline); }
body.la-app .app-luoi-nho .app-bt .btm { width: 44px; height: 44px; }
body.la-app .app-luoi-nho .app-ten {
  font-size: 11.5px; line-height: 1.3; margin-top: 0; -webkit-line-clamp: 3;
}
/* Tên việc chỉ còn hai dòng khi ô có thêm dòng giá — ba dòng tên cộng một
   dòng số là ô cao hơn ô không có giá, hàng lưới so le. */
body.la-app .app-luoi-nho .app-o:has(.app-o-gia) .app-ten { -webkit-line-clamp: 2; }
body.la-app .app-o-gia { color: var(--md-primary); }
body.la-app .app-luoi-chu {
  color: var(--md-on-surface-variant);
  font: 400 12px/1.5 Roboto, system-ui, sans-serif;
}

/* --- Giá trong trang từng dịch vụ -----------------------------------------
   Trước đây tám dòng giá xếp thành một bảng ở màn hình đầu. Bảng ấy bỏ rồi:
   nó bắt người ta dò tên việc của mình giữa tám dòng, trong khi bấm vào đúng
   ô việc là tới thẳng trang này. Ở đây chỉ còn MỘT con số, nên nó được to.

   Nhãn nằm trên, số nằm dưới — không xếp trái/phải như bảng cũ. Trang này con
   số là thứ khách xuống tìm; cho nó đứng riêng một dòng thì mắt bắt được ngay
   mà không phải quét ngang. */
body.la-app .app-dv-gia {
  display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  margin: 14px 0 8px; padding: 12px 15px 13px; border-radius: 16px;
  background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline-variant);
}
body.la-app .app-dv-gia-nhan {
  font: var(--md-label-m); letter-spacing: .3px; text-transform: uppercase;
  color: var(--md-on-surface-variant);
}
body.la-app .app-dv-gia-so {
  font: 700 27px/1.15 "Roboto Mono", ui-monospace, monospace;
  color: var(--md-primary); font-variant-numeric: tabular-nums;
}
/* "từ" là chú thích của con số chứ không phải một phần con số — nhỏ, mờ, và
   KHÔNG mono, để mắt không đọc nó thành chữ số. */
body.la-app .app-dv-gia-so i {
  font: 400 13px/1 Roboto, system-ui, sans-serif;
  color: var(--md-on-surface-variant); margin-right: 3px;
}
/* Khoảng giá là hai con số trong một dòng — ở 27px nó xuống hàng ngay giữa
   chữ "đến", đọc thành hai giá rời. Bóp theo bề ngang máy để nó ở lại một
   dòng; vẫn là con số to nhất màn hình này. */
body.la-app .app-dv-gia-khoang {
  font-size: clamp(18px, 6.1vw, 24px);
}
/* Hai trạng thái không-có-số thì thôi làm số to: chúng là chữ, để nguyên dạng
   viên thuốc như cũ, cỡ chữ thường. */
body.la-app .app-gia-hoi,
body.la-app .app-gia-mp {
  font: var(--md-label-m); letter-spacing: .2px; padding: 5px 11px;
  border-radius: 999px; color: var(--md-on-secondary-container);
  background: var(--md-secondary-container);
}
body.la-app .app-dv-gia-so.app-gia-hoi,
body.la-app .app-dv-gia-so.app-gia-mp { font: var(--md-label-m); }
@media (prefers-reduced-motion: reduce) {
  body.la-app .app-o,
  body.la-app .app-luoi-nho .app-bt { transition: none; }
  body.la-app .app-o:active .app-bt { transform: none; }
  /* JS đã tự đứng im khi máy bật "giảm chuyển động", nhưng chặn thêm ở đây:
     luật CSS đúng kể cả khi JS chưa chạy hoặc bị chặn. */
  body.la-app .app-luoi-nho .app-bt.dong { animation: none; }
}

/* --- Thẻ đơn máy nhớ giùm -------------------------------------------------
   Nền volt đặc: đây là thứ duy nhất trên màn hình dành riêng cho người đã gửi
   vợt, và họ mở app ra chỉ để bấm đúng nó. */
body.la-app .app-luu {
  display: flex; align-items: center; gap: 8px; margin: 0 0 12px;
  padding: 8px 8px 8px 12px; border-radius: 14px;
  background: linear-gradient(160deg, var(--green-2) 0%, var(--md-primary-container) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7), 0 4px 12px -7px rgba(60, 74, 0, .5);
}
body.la-app .app-luu-mo {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 9px;
  background: none; border: none; padding: 4px 0; min-height: 0;
  font: var(--md-label-l); color: var(--md-on-primary-container);
  text-align: left; cursor: pointer;
}
body.la-app .app-luu-mo .bt { width: 20px; height: 20px; flex: none; }
body.la-app .app-luu-mo .so { font-family: "Roboto Mono", ui-monospace, monospace; }
body.la-app .app-luu-quen {
  flex: none; min-height: 32px; padding: 0 12px; border-radius: 999px;
  background: rgba(255, 255, 255, .55); border: none;
  font: var(--md-label-m); color: var(--md-on-primary-container); cursor: pointer;
}

/* --- Khối gấp "Trạm làm thế nào" -----------------------------------------
   Bóp cho khớp bốn khối trên: bản cũ bo 14px kèm padding 16px, đứng ngay dưới
   thẻ cam kết bo 14px thì lệch một sợi tóc — không ai chỉ ra được là lệch,
   nhưng nhìn vào thấy xộc xệch. */
body.la-app .app-gap {
  border-radius: 14px; background: var(--md-surface-container-lowest);
  border: 1px solid var(--md-outline-variant); margin-top: 14px;
}
body.la-app .app-gap:first-of-type { margin-top: 14px; }
body.la-app .app-gap > summary { padding: 10px 12px; gap: 11px; }
body.la-app .app-gap-bt {
  flex: none; width: 38px; height: 38px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  color: var(--md-on-primary-container);
  background: linear-gradient(158deg, var(--green-2) 0%, var(--md-primary-container) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .75), 0 4px 9px -5px rgba(60, 74, 0, .55);
}
body.la-app .app-gap-bt .bt { width: 20px; height: 20px; }
body.la-app .app-gap-ten { font: var(--md-title-m); font-size: 14.5px; }

/* --- Thanh dưới đáy -------------------------------------------------------
   Navigation bar của M3: nền surface-container, nhãn label-medium, mục đang
   mở có viên thuốc volt sau icon. */
body .app-chan {
  background: var(--md-surface-container);
  border-top: 1px solid var(--md-outline-variant);
}
body .app-chan a { font: var(--md-label-m); gap: 2px; padding: 8px 3px 9px; }
body .app-chan a.dang { color: var(--md-on-surface); font-weight: 700; }
body .app-chan a .bt { width: 22px; height: 22px; }
body .app-chan a.app-chi-duong { color: #d32f2f; }
/* Viên thuốc sau icon của mục đang mở. M3 báo mục đang mở bằng cái này chứ
   không bằng đổi màu chữ. Viên thuốc nay tô ô-liu nên nét icon phải lật sang
   trắng — nét tối trên mảng tối là không thấy gì. */
body .app-chan a.dang > .bt:first-child,
body .app-chan a.dang > svg:first-child {
  background: var(--md-primary-container); color: var(--md-on-primary-container);
  border-radius: 999px;
  padding: 3px 14px; box-sizing: content-box; width: 22px; height: 22px;
}
body .app-chan-tron .tron {
  background: linear-gradient(158deg, var(--green-2) 0%, var(--md-primary-container) 100%);
  color: var(--md-on-primary-container); border-color: var(--md-surface-container);
  box-shadow: 0 6px 16px -6px rgba(60, 74, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .8);
}

/* ==========================================================================
   KHỐI NỔI CHO HÌNH DỊCH VỤ — cái Kendy gọi là "dạng 4D"
   Tám hình việc là SVG phẳng: một ô bo góc màu, thân vợt tô đặc, chỗ hỏng tô
   cam. Đọc thì rõ, nhưng nằm cạnh nhau trông vẫn là hình vẽ dán lên giấy.

   Không sửa 12 tệp SVG để thêm chuyển sắc vào từng hình — sửa một chỗ ở đây
   là xong cả tám, và hình gốc giữ nguyên để còn dùng lại ở trang web.
   Ba lớp làm nên chiều sâu:
     1. drop-shadow theo đúng hình bo góc  → vật có bóng, tức là nó nổi trên
        mặt phẳng chứ không nằm trong mặt phẳng.
     2. men bóng phủ trên (::after)        → sáng ở nửa trên, tối ở mép dưới,
        đúng cách ánh sáng rơi lên một khối lồi.
     3. hai vạch inset                     → cạnh vát trên và chân tối dưới.
   Chỉ áp trong .app-luoi-nho: đấy là chỗ hình vuông đúng cỡ. Icon nét ở chỗ
   khác mà phủ men vào thì thành ô vuông mờ, không ra hình gì.
   ========================================================================== */
body.la-app .app-luoi-nho .app-bt {
  position: relative; display: inline-flex;
  transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
}
body.la-app .app-o:active .app-bt { transform: scale(.86) rotate(-7deg); }

/* Nhúc nhích một mình. Mỗi nhịp JS gắn .dong vào ĐÚNG MỘT icon rồi gỡ ra —
   tám icon cùng nhảy thì màn hình thành cái đèn nháy, mắt không biết đậu vào
   đâu và nhìn vài giây là mỏi. Một cái động giữa bảy cái đứng yên thì mắt tự
   bị kéo tới, đấy mới là thứ muốn.

   Cùng đường cong vượt đà với cú chạm (.34,1.56 và .34,1.4) nên hai chuyển
   động là họ hàng: cái tự chạy trông như cái người ta vừa bấm, nhẹ hơn một
   chút. Khác cong là icon động ra một kiểu, bấm ra một kiểu, thành hai vật
   khác nhau.

   Không đặt animation-fill-mode: hết animation thì transform trả về giá trị
   thường, để :active lúc chạm vẫn ăn. (JS còn gỡ .dong ngay lúc pointerdown
   nữa — animation đang chạy thì đè lên :active, ngón tay bấm mà icon không
   lún xuống là mất cảm giác bấm.) */
@keyframes app-bt-nhun {
  0%   { transform: scale(1) rotate(0deg); }
  20%  { transform: scale(.88) rotate(-7deg); }
  46%  { transform: scale(1.12) rotate(5deg); }
  70%  { transform: scale(.98) rotate(-2deg); }
  100% { transform: scale(1) rotate(0deg); }
}
body.la-app .app-luoi-nho .app-bt.dong {
  animation: app-bt-nhun .68s cubic-bezier(.34, 1.4, .64, 1);
}
body.la-app .app-luoi-nho .app-bt .btm {
  border-radius: 29.2%;                       /* = rx 7 trên khung 24 của SVG */
  filter:
    drop-shadow(0 3px 4px rgba(28, 36, 6, .30))
    drop-shadow(0 1px 1px rgba(28, 36, 6, .16));
}
body.la-app .app-luoi-nho .app-bt::after {
  content: ""; position: absolute; inset: 0; border-radius: 29.2%;
  pointer-events: none;
  background: linear-gradient(177deg,
    rgba(255, 255, 255, .60) 0%,
    rgba(255, 255, 255, .10) 33%,
    rgba(255, 255, 255, 0) 51%,
    rgba(24, 30, 6, .09) 80%,
    rgba(24, 30, 6, .21) 100%);
  box-shadow:
    inset 0 1.2px 0 rgba(255, 255, 255, .92),
    inset 0 -1.4px 2px rgba(24, 30, 6, .20);
}
/* Nhấn xuống thì khối lún: bóng co lại, men mờ đi. Cả ô .app-o cũng đang hạ
   1px, hai thứ đi cùng nhau mới ra cảm giác bấm vào vật thật. */
body.la-app .app-o:active .app-bt .btm {
  filter: drop-shadow(0 1px 2px rgba(28, 36, 6, .34));
}
body.la-app .app-o:active .app-bt::after { opacity: .55; }

/* Logo trên bảng hiệu cũng là hình phẳng — cho nó cùng một nguồn sáng với
   tám ô bên dưới, nếu không thì đầu trang trông dán lên, thân trang nổi lên. */
body.la-app .app-bia .logo-dau,
body.la-app .app-bia .logo-4d,
body.la-app .app-bia .chu-tpic {
  filter:
    drop-shadow(0 3px 4px rgba(46, 42, 94, .26))
    drop-shadow(0 1px 0 rgba(255, 255, 255, .55));
}

/* ==========================================================================
   THANH TẢI TRÊN ĐỈNH — chạy lúc đang sang trang
   Trang này dựng ở máy chủ, bấm link là trình duyệt đi lấy trang mới. Khoảng
   giữa lúc bấm và lúc trang mới hiện ra, màn hình đứng im y hệt như lúc chưa
   bấm — khách tưởng nút chết nên bấm lại lần nữa. Một vạch chạy trên đỉnh là
   câu trả lời rẻ nhất: "nghe rồi, đang đi lấy".

   Chờ 90ms mới hiện (đoạn JS trong pwa.html): mạng nhanh thì trang mới về
   trước lúc ấy, mà một vạch loé lên 40ms rồi tắt còn khó chịu hơn không có gì.
   ========================================================================== */
.app-tai {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 90;
  pointer-events: none; overflow: hidden;
  opacity: 0; transition: opacity .16s linear;
  background: rgba(78, 96, 0, .13);   /* máy cũ chưa biết color-mix */
  background: color-mix(in srgb, var(--sang-muc) 14%, transparent);
}
.app-tai i {
  display: block; width: 100%; height: 100%; border-radius: 0 3px 3px 0;
  transform: translateX(-100%) scaleX(.3); transform-origin: 0 50%;
  background: linear-gradient(90deg,
    rgba(78, 96, 0, .5) 0%, var(--sang) 62%, #fff 100%);
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--sang-muc) 55%, transparent) 0%,
    var(--sang) 62%, #fff 100%);
}
html.dang-tai .app-tai { opacity: 1; }
html.dang-tai .app-tai i { animation: app-tai-chay 1.05s cubic-bezier(.35, 0, .2, 1) infinite; }
@keyframes app-tai-chay {
  0% { transform: translateX(-100%) scaleX(.3); }
  52% { transform: translateX(52%) scaleX(.62); }
  100% { transform: translateX(210%) scaleX(.3); }
}
/* Máy xin bớt chuyển động: vẫn phải biết là trang đang đi, nên giữ vạch
   nhưng để nó đứng yên một đoạn chứ không chạy. */
@media (prefers-reduced-motion: reduce) {
  html.dang-tai .app-tai i { animation: none; transform: translateX(0) scaleX(.4); }
}

/* ==========================================================================
   NÚT LIÊN HỆ GIỮA THANH ĐÁY — số điện thoại và Zalo chung một chỗ
   Kendy: "Zalo phải cùng với cái sđt vì nó là liên hệ". Đúng. Hai thứ ấy là
   hai đường tới cùng một người; xếp thành hai ô ngang hàng là bắt khách chọn
   giữa hai cái giống nhau, mà lại ăn mất ô thứ năm vốn dẫn vào Quy trình. Nay
   ô năm trả về Quy trình, nút giữa nở ra hai dòng khi bấm.

   Dùng <details> chứ không dựng menu bằng JS: mở/đóng là việc trình duyệt làm
   sẵn, JS chỉ còn đúng một việc — đóng khi bấm ra chỗ khác. Máy tắt JS vẫn
   bấm mở bấm đóng được.

   Luật `.app-chan a` không với tới <details>, nên phần căn chỉnh phải khai
   lại đủ ở đây. Trông thừa nhưng không thừa: xoá dòng nào là nút giữa tụt
   khỏi hàng dòng ấy.
   ========================================================================== */
.app-chan details.app-lh { flex: 1 1 0; flex-grow: 1.3; min-width: 0; position: relative; }
.app-chan details.app-lh > summary {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 0 3px 10px; color: var(--muc); font-weight: 650;
  font-size: 11px; line-height: 1.2; text-align: center;
  list-style: none; cursor: pointer;
}
.app-chan details.app-lh > summary::-webkit-details-marker { display: none; }
.app-chan details.app-lh > summary::marker { content: ""; }
.app-chan details.app-lh > summary:active .tron { filter: brightness(.93); }
.app-chan details.app-lh[open] > summary .tron { filter: brightness(.93); }

/* Hai dòng bật lên: neo vào nút, mở NGƯỢC LÊN TRÊN. Nút nằm sát đáy màn hình
   nên mở xuống là chui ra ngoài. translateX(-50%) để bảng nằm giữa nút chứ
   không lệch — nút giữa rộng hơn bốn nút kia, canh theo mép trái là lệch. */
.app-chan .app-lh-menu {
  position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%);
  z-index: 40; min-width: 212px; padding: 6px;
  border-radius: 16px; background: var(--the); border: 1px solid var(--vien);
  box-shadow: 0 14px 34px -12px rgba(46, 42, 94, .58), 0 2px 8px rgba(46, 42, 94, .14);
}
.app-chan .app-lh-menu a {
  display: flex; flex-direction: row; align-items: center; gap: 11px;
  padding: 9px 11px; border-radius: 11px; text-align: left;
  color: var(--muc); text-decoration: none; font-size: 14px; font-weight: 650;
}
.app-chan .app-lh-menu a:active { background: var(--th-nen); }
.app-chan .app-lh-menu .bt { flex: none; width: 22px; height: 22px; color: var(--sang-muc); }
.app-chan .app-lh-menu a span { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.app-chan .app-lh-menu a b {
  font: 400 12px/1.25 "Roboto Mono", ui-monospace, monospace;
  color: var(--muc-mo); font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}

/* ==========================================================================
   MÀN HÌNH ĐẦU GÓI TRONG ĐÚNG MỘT MÀN — body.la-app.man-1
   Kendy chốt: "tất cả cho vào 1 trang không có kéo chuột". Trang này KHÔNG
   cuộn, không vuốt ngang. Mọi thứ phải lọt giữa bảng hiệu và thanh đáy.

   ĐO BẰNG KHUNG NHÌN, KHÔNG ĐO BẰNG MÀN HÌNH MÁY. Bài học đã trả giá một lần,
   ghi ra đây để đừng trả lần nữa: bản trước bóp theo ba nấc @media
   (700 / 660 / 620px) và nghiệm thu bằng chiều cao MÀN HÌNH máy — 844, 667,
   640. Sai chỗ đó. Khung nhìn thật của trình duyệt là màn hình TRỪ thanh địa
   chỉ và thanh điều hướng, hụt đi 100-150px:
     iPhone 390x844  → còn ~700px, trên ngưỡng 620 nên vừa.
     Android 360x640 → còn ~510px, RƠI XUỐNG dưới 620 nên trúng nấc cuối, mà
     nấc ấy chính là nấc "trả lại cách cuộn cũ".
   Kendy báo đúng hiện tượng ấy: "iphone thì full còn android ko full".

   → Không còn nấc nào để rơi qua. Mọi kích thước ở đây là
     clamp(sàn, k·svh, trần): co LIÊN TỤC theo khung nhìn thật. Sàn là ngưỡng
     đọc được, trần là cỡ dễ chịu trên máy cao.
   → svh chứ không dvh: svh đo lúc thanh địa chỉ ĐANG HIỆN, tức lúc chật nhất,
     và nó là hằng số — dvh đổi giá trị giữa chừng khi thanh trượt đi, kéo cả
     trang giật lên giật xuống theo.
   → Ngưỡng bỏ cuộc hạ từ 620 xuống 430: dưới 430 là điện thoại xoay ngang, ở
     đó không bố cục nào cứu được, thà cuộn.

   Cách chia chiều cao: body là cột flex ba phần. Bảng hiệu và thanh đáy giữ
   chiều cao thật của chúng; thân ở giữa nhận hết phần còn lại. Trong thân, ba
   khối chữ khoá theo clamp, banner nuốt nốt phần thừa — máy cao banner nở ra,
   máy thấp banner co lại. Thứ hi sinh trước là hình, không phải chữ.

   Thanh đáy chuyển từ fixed sang static: đã là cột flex thì để nó tự chiếm
   chỗ, khỏi đoán chiều cao rồi chừa đệm — đoán sai một lần là hoặc thừa dải
   trắng, hoặc nuốt mất dòng cuối.
   ========================================================================== */
body.la-app.man-1 {
  height: 100vh;                      /* máy cũ chưa biết svh */
  height: 100svh;
  overflow: hidden;
  display: flex; flex-direction: column;
  /* body.la-app chừa 76px dưới đáy cho thanh cố định. Ở đây thanh ấy đã thành
     static trong cột flex, để nguyên padding là thừa hẳn một dải trắng. */
  padding-bottom: 0;
}

/* --- Bảng hiệu ----------------------------------------------------------- */
body.la-app.man-1 .app-bia {
  flex: none;
  padding: calc(clamp(4px, .9svh, 9px) + env(safe-area-inset-top, 0px)) var(--app-le) clamp(4px, .8svh, 7px);
}
body.la-app.man-1 .app-bia-lk { gap: clamp(7px, 1.3svh, 11px); }
body.la-app.man-1 .app-bia .logo-dau,
body.la-app.man-1 .app-bia .logo-4d { height: clamp(26px, 4.25svh, 36px); }
/* Màn hình đơn không cuộn: chữ phải co theo svh y như hình, nếu không thì
   máy màn ngắn bị đội thêm 11px cứng và thanh đáy tụt khỏi màn. */
body.la-app.man-1 .app-bia .chu-tpic { height: clamp(7.5px, 1.2svh, 10px); }
body.la-app.man-1 .app-bia .logo-khoi { gap: clamp(1px, .25svh, 2px); }
body.la-app.man-1 .app-bia-ten { font-size: clamp(15px, 2.05svh, 17px); }
body.la-app.man-1 .app-bia-mo { font-size: clamp(10px, 1.4svh, 11.5px); }
/* --- Dải địa chỉ --------------------------------------------------------
   Co theo svh như mọi thứ khác ở màn không cuộn. Dải này tuy không đẩy thanh
   đáy tụt xuống (banner nuốt phần chênh), nhưng mỗi điểm ảnh nó giữ lại là
   một điểm ảnh banner mất đi — máy màn ngắn banner đã sát trần dưới 44px. */
body.la-app.man-1 .app-cho {
  padding: clamp(4px, .75svh, 7px) clamp(8px, 1.35svh, 11px);
  gap: clamp(6px, 1svh, 8px); border-radius: clamp(9px, 1.5svh, 12px);
}
body.la-app.man-1 .app-cho-nhan { font-size: clamp(8.5px, 1.2svh, 10px); }
body.la-app.man-1 .app-cho > .bt {
  width: clamp(14px, 2.2svh, 18px); height: clamp(14px, 2.2svh, 18px);
}
body.la-app.man-1 .app-cho-chu { font-size: clamp(11px, 1.55svh, 12.5px); }

/* --- Thanh đáy ----------------------------------------------------------- */
body.la-app.man-1 .app-chan { position: static; flex: none; }
body.la-app.man-1 .app-chan a {
  padding-top: clamp(5px, .95svh, 9px); padding-bottom: clamp(5px, 1.05svh, 10px);
}
body.la-app.man-1 .app-chan a.app-chan-tron { padding-top: 0; }
body.la-app.man-1 .app-chan details.app-lh > summary {
  padding-bottom: clamp(5px, 1.05svh, 10px);
}
body.la-app.man-1 .app-chan .bt {
  width: clamp(19px, 2.7svh, 22px); height: clamp(19px, 2.7svh, 22px);
}
body.la-app.man-1 .app-chan-tron .tron {
  width: clamp(42px, 6.4svh, 54px); height: clamp(42px, 6.4svh, 54px);
  margin-top: clamp(-24px, -2.85svh, -16px); border-width: clamp(3px, .45svh, 4px);
}
body.la-app.man-1 .app-chan-tron .tron .bt {
  width: clamp(20px, 3svh, 25px); height: clamp(20px, 3svh, 25px);
}
body.la-app.man-1 .app-chan-so { font-size: clamp(9.5px, 1.28svh, 10.5px); }

/* --- Thân ---------------------------------------------------------------- */
body.la-app.man-1 .app-than {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; flex-direction: column; gap: clamp(5px, .95svh, 8px);
  padding: 0 var(--app-le) clamp(5px, .95svh, 8px);
}
body.la-app.man-1 .app-than > * { flex: none; }
body.la-app.man-1 .app-luu { margin: 0; }

/* --- Banner: phần co giãn duy nhất ---------------------------------------
   Mặc định là chữ + bản vẽ vợt (hinh-vot-hero), không phải ảnh chụp: khe này
   cao 60-240px và rất ngang, ảnh chụp cắt vào đây thường còn một vệt màu
   không đọc ra cái gì mà vẫn nặng vài trăm KB cho cái vệt ấy. Bản vẽ nhẹ, sắc
   ở mọi cỡ màn, và nói được một câu chào hàng.

   Nhưng đấy là mặc định chứ không phải luật. Chủ trạm chọn được một tấm ở
   /qt/app thì banner đổi sang ảnh ấy (.co-anh) — có ảnh chụp đúng khổ ngang,
   chủ thể lệch phải, thì ảnh thật vẫn hơn hình vẽ. Bỏ chọn là về lại bản vẽ,
   không mất gì.

   min-height là cái phanh: dưới 44px thì chữ không lọt. max-height là cái
   phanh ngược: flex:1 khiến banner nuốt hết phần thừa, máy cao mà không chặn
   thì nó cao bằng cả lưới việc bên dưới. Ẩn hẳn banner ở /qt/app thì cả khối
   biến mất, phần thừa chảy sang lưới việc — lưới cũng flex:1 nên không phải
   sửa gì thêm. */
body.la-app.man-1 .app-bang1 {
  flex: 1 1 auto;
  min-height: clamp(44px, 8svh, 92px); max-height: clamp(60px, 30svh, 240px);
  margin: 0; position: relative; overflow: hidden; border-radius: 16px;
  display: flex; align-items: center;
  padding: clamp(7px, 1.4svh, 16px) clamp(11px, 2svh, 18px);
  background:
    radial-gradient(120% 155% at 86% 14%, rgba(255, 199, 44, .34) 0%, rgba(255, 199, 44, 0) 56%),
    linear-gradient(122deg, #231F47 0%, #393172 54%, #16132F 100%);
  box-shadow: 0 8px 20px -10px rgba(46, 42, 94, .5), 0 1px 2px rgba(46, 42, 94, .14);
}
/* Ảnh đè lên nền volt, không trộn với nó: background rút gọn ghi đè cả hai
   lớp gradient bên trên. Giữ nguyên box-shadow để khối vẫn nổi khỏi mặt nền.

   ::before là lớp phủ tối, và nó phải là gradient chứ không phải một màu đen
   mờ đều: chữ chỉ nằm ở nửa trái (max-width 63%) nên bên trái cần tối để chữ
   đọc được, bên phải cần sáng để còn nhìn ra ảnh. Phủ đều một mức thì hoặc
   chữ mờ, hoặc ảnh thành cục than. Độ đậm --toi do chủ trạm chọn ở /qt/app,
   vì nó phụ thuộc vào tấm ảnh chứ không phải vào bố cục — ảnh chụp ngoài nắng
   và ảnh chụp trong xưởng cần hai mức khác hẳn nhau. */
body.la-app.man-1 .app-bang1.co-anh {
  background: var(--anh) center / cover no-repeat #231F47;
}
/* Video nền. Nằm dưới lớp phủ tối (z-index 1) và dưới chữ (z-index 2), phủ
   kín khung bằng object-fit: cover — khung banner cao theo màn hình nên tỉ lệ
   của nó không bao giờ khớp tỉ lệ clip, và thà cắt mép còn hơn để hai vệt đen
   hai bên.

   pointer-events: none để chạm vào banner không đánh thức bộ điều khiển video
   của trình duyệt. Khách chạm vào đây là đang định bấm cái gì đó, không phải
   định tạm dừng một đoạn phim nền.

   Nền phía sau trả về ĐÚNG bộ gradient volt mặc định, không phải một màu
   trơn. Hai lý do: khung hình đầu chưa về thì chỗ này vẫn phải trông như một
   banner chứ không phải ô đen, và .co-video luôn đi kèm .co-anh — mà .co-anh
   đặt background: var(--anh)..., nên khi có video nhưng chưa chọn ảnh thì
   --anh không tồn tại và cả khai báo ấy hỏng, để lại nền trong suốt. Dòng
   dưới đứng sau nên thắng, và vá luôn cái lỗ đó. */
body.la-app.man-1 .app-bang1.co-video {
  background:
    radial-gradient(120% 155% at 86% 14%, rgba(255, 199, 44, .34) 0%, rgba(255, 199, 44, 0) 56%),
    linear-gradient(122deg, #231F47 0%, #393172 54%, #16132F 100%);
}
body.la-app.man-1 .app-bang1-video {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
  pointer-events: none;
}
body.la-app.man-1 .app-bang1.co-anh::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(96deg,
    rgba(11, 9, 23, calc(var(--toi) + 18%)) 0%,
    rgba(11, 9, 23, var(--toi)) 52%,
    rgba(11, 9, 23, calc(var(--toi) * .5)) 100%);
}
/* Ảnh chụp có chỗ sáng bất ngờ; thêm một vệt bóng ngay sau chữ để dòng lớn
   không rơi vào đúng một mảng trắng. Rẻ hơn nhiều so với bắt chủ trạm phải
   sửa ảnh trước khi tải lên. */
body.la-app.man-1 .app-bang1.co-anh .app-bang1-chu b,
body.la-app.man-1 .app-bang1.co-anh .app-bang1-chu span {
  text-shadow: 0 1px 3px rgba(9, 8, 20, .55);
}
/* 78% chứ không 63% như bản "Vợt hỏng, sửa được": dòng lớn nay là hai nghề
   xuống dòng thủ công, dòng dài nhất là "Thay đế giày thể thao". Để 72% thì
   trên máy 360px dòng ấy vẫn tự ngắt thêm một lần nữa thành ba dòng, banner
   phải cao thêm ~24px — chỗ ấy phải lấy từ lưới việc. Bản vẽ vợt nằm tràn mép
   phải, phần bị chữ lấn vào là phần đã ra ngoài khung, nên nới bề ngang chữ
   không che mất hình. */
body.la-app.man-1 .app-bang1-chu {
  position: relative; z-index: 2; max-width: 78%;
  display: flex; flex-direction: column; gap: clamp(1px, .38svh, 4px);
}
/* pre-line: chủ trạm gõ Enter ở /qt/app thì banner xuống dòng đúng chỗ ấy.
   Không dùng <br> cứng trong template vì câu này là chữ CMS — nhét thẻ vào
   thì nd phải cho phép HTML, mà cho phép HTML ở một ô chữ thì mở luôn đường
   dán thẻ bậy vào. pre-line vẫn gộp khoảng trắng thừa và VẪN tự ngắt khi
   dòng dài quá, nên máy hẹp không bị tràn chữ ra ngoài khung. */
body.la-app.man-1 .app-bang1-chu b {
  font: 700 clamp(14.5px, 2.32svh, 21px)/1.16 Roboto, system-ui, sans-serif;
  color: var(--lime-nhat); letter-spacing: -.012em;
  white-space: pre-line;
}
body.la-app.man-1 .app-bang1-phu {
  font: 400 clamp(10px, 1.42svh, 13px)/1.32 Roboto, system-ui, sans-serif;
  color: rgba(249, 237, 200, .76);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Bản vẽ tràn ra khỏi mép: cắt cụt là cố ý. Cây vợt nằm gọn trong khung thì
   nó là cái tem dán vào góc; tràn mép thì khung mới trông như cửa sổ nhìn vào
   một chỗ rộng hơn. Nghiêng 11 độ cho khỏi song song với mép khung. */
body.la-app.man-1 .app-bang1-hinh {
  position: absolute; right: -3%; bottom: -20%; z-index: 1;
  height: min(172%, 258px); aspect-ratio: 440 / 570; pointer-events: none;
  transform: rotate(-11deg);
}
body.la-app.man-1 .app-bang1-hinh .sv {
  width: auto; height: 100%;
  --sv-net: rgba(255, 225, 148, .82);
  --sv-mo: rgba(255, 225, 148, .26);
  --sv-nhan: var(--lime);
  --sv-to: rgba(255, 199, 44, .15);
  --sv-canh: #F0A184;
}

/* --- Ba khối chữ --------------------------------------------------------- */
body.la-app.man-1 .app-than section.app-muc {
  margin: 0; border-radius: 14px;
  padding: clamp(6px, 1.05svh, 9px) clamp(8px, 1.2svh, 10px) clamp(7px, 1.15svh, 10px);
}
body.la-app.man-1 .app-muc-ten {
  margin: 0 0 clamp(4px, .8svh, 7px);
  font: 500 clamp(12px, 1.66svh, 14px)/1.42 Roboto, system-ui, sans-serif;
}
body.la-app.man-1 .app-muc-ten::before { height: clamp(11px, 1.55svh, 13px); }

/* --- Lưới việc: vẫn 4 cột, ô thấp lại, chữ hai dòng ----------------------- */
body.la-app.man-1 .app-luoi-nho { gap: clamp(4px, .83svh, 7px); }
body.la-app.man-1 .app-o {
  padding: clamp(4px, .95svh, 8px) 4px; gap: clamp(3px, .6svh, 5px); border-radius: 13px;
}
body.la-app.man-1 .app-luoi-nho .app-bt .btm {
  width: clamp(30px, 5.6svh, 44px); height: clamp(30px, 5.6svh, 44px);
}
body.la-app.man-1 .app-luoi-nho .app-ten {
  font-size: clamp(9px, 1.24svh, 10.5px); line-height: 1.22; -webkit-line-clamp: 2;
}
body.la-app.man-1 .app-o-gia { font-size: clamp(8.5px, 1.16svh, 10px); line-height: 1.2; }
/* Câu chú thích nằm ngoài phần co giãn: lưới là thứ được chia chỗ thừa, câu
   này chỉ lấy đúng chiều cao một dòng của nó. */
body.la-app.man-1 .app-luoi-chu {
  flex: none; margin: clamp(5px, .9svh, 9px) 4px 0;
  font-size: clamp(9.5px, 1.24svh, 11.5px); line-height: 1.38;
}

/* --- Chia lại chỗ trống ---------------------------------------------------
   Bỏ khối giá và khối cam kết là màn hình dôi ra hơn 200px. Để trống thì đáy
   màn hở một mảng, trông như trang bị cụt chứ không như trang gọn.

   Chia cho hai khối còn lại, và chia theo cách khác nhau:
     banner  — cao thêm, vì nó là hình, hình to thì đẹp hơn chứ không loãng.
     lưới việc — ô cao thêm chứ không thêm ô. Tám việc vẫn là tám việc; ô to
                 lên thì ngón tay bấm trúng dễ hơn, đó là lợi ích thật.
   Cả hai đều flex:1 nên khi khuyến mãi bật/tắt, phần chênh tự chảy vào hai
   chỗ này — không phải chỉnh tay hai bố cục. */
body.la-app.man-1 .app-muc-luoi {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  max-height: clamp(186px, 52svh, 430px);
}
/* Ẩn banner ở /qt/app là dôi ra hơn 200px không ai nhận. Đã thử nới trần lưới
   cho nó nuốt hết: ô cao 225px cho một icon 44px, icon lọt thỏm giữa ô trắng,
   xấu hơn hẳn. Nên chỗ thừa không cho ai cả — chia đều lên trên xuống dưới.
   Dư ở hai đầu trông như khoảng thở; dồn hết xuống đáy mới trông như trang bị
   cụt.

   Luật này chung cho mọi trạng thái, không riêng lúc ẩn banner: khi chỗ thừa
   bằng 0 (gần như luôn luôn, vì banner và lưới đều flex:1) thì nó không làm
   gì cả. Dưới 430px khung nhìn .app-than thành display:block nên luật cũng tự
   hết tác dụng. */
body.la-app.man-1 .app-than { justify-content: center; }
body.la-app.man-1 .app-muc-luoi .app-luoi-nho {
  flex: 1 1 auto; min-height: 0; grid-auto-rows: 1fr;
}
body.la-app.man-1 .app-o { justify-content: center; }

/* --- Khuyến mãi -----------------------------------------------------------
   Một dòng bấm được, không phải cái thẻ to. Khối này bật/tắt theo mùa; nếu
   nó chiếm nửa màn thì lúc tắt màn hình lại phải bố trí kiểu khác. Giữ nó
   thấp và flex:none là hai bố cục chỉ chênh nhau đúng chiều cao một dòng.

   Nền volt đặc — nó phải nổi hơn lưới việc bên trên, vì nội dung ở đây là
   thứ có hạn, xem muộn là mất. */
body.la-app.man-1 .app-muc-km { flex: none; }
body.la-app.man-1 .app-km {
  display: flex; align-items: center; gap: clamp(8px, 1.3svh, 11px);
  padding: clamp(7px, 1.2svh, 10px) clamp(10px, 1.5svh, 13px);
  border-radius: 13px; text-decoration: none; position: relative;
  color: var(--md-on-primary-container);
  background: linear-gradient(160deg, var(--green-2) 0%, var(--md-primary-container) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 5px 12px -7px rgba(60, 74, 0, .5);
}
body.la-app.man-1 .app-km:active { box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6); }
body.la-app.man-1 .app-km-huy {
  flex: none; padding: 3px clamp(6px, .9svh, 8px); border-radius: 999px;
  font: 700 clamp(9px, 1.15svh, 10.5px)/1.3 Roboto, system-ui, sans-serif;
  letter-spacing: .5px; color: var(--lime-nhat); background: var(--forest-2);
}
body.la-app.man-1 .app-km-huy:empty { display: none; }
body.la-app.man-1 .app-km-chu {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px;
}
body.la-app.man-1 .app-km-chu b {
  font: 700 clamp(12px, 1.66svh, 14.5px)/1.25 Roboto, system-ui, sans-serif;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.la-app.man-1 .app-km-chu i {
  font: 400 clamp(9.5px, 1.24svh, 11.5px)/1.28 Roboto, system-ui, sans-serif;
  font-style: normal; opacity: .72;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
body.la-app.man-1 .app-km-chu i:empty { display: none; }
/* Mũi tên vẽ bằng hai nét viền xoay 45 độ. Bộ Material Symbols nhúng là bản
   cắt 36 icon, không có mũi tên phải — thêm một cái tên là phải dựng lại
   font. Không đáng cho một hình chữ V. */
body.la-app.man-1 .app-km::after {
  content: ""; flex: none; width: 7px; height: 7px; margin-right: 2px;
  border-right: 2px solid currentColor; border-top: 2px solid currentColor;
  transform: rotate(45deg); opacity: .55;
}
/* --- Dưới 545px khung nhìn: bớt chữ, KHÔNG bớt cỡ chữ ---------------------
   Tới đây clamp đã chạm sàn ở khắp nơi, bóp nữa là chữ nhỏ hơn ngưỡng đọc.
   Còn đúng một cách: bỏ bớt thứ để đọc. Bỏ dòng phụ của banner, bỏ dòng hạn
   của khuyến mãi, cắt tên việc trong lưới còn một dòng. Đổi lại chữ giữ
   nguyên cỡ. */
@media (max-height: 545px) {
  body.la-app.man-1 .app-bang1-phu { display: none; }
  body.la-app.man-1 .app-bang1-chu { max-width: 84%; }
  body.la-app.man-1 .app-km-chu i { display: none; }
  body.la-app.man-1 .app-luoi-nho .app-ten { -webkit-line-clamp: 1; }
  /* Con số trong ô vẫn còn — đó là thứ khách vào đây để xem. Bỏ câu giải
     thích dưới lưới, nó lặp lại điều mà dấu gạch trong "100–150k" đã nói. */
  body.la-app.man-1 .app-luoi-chu { display: none; }
}

/* --- Dưới 720px: bỏ cuộc, trả lại cách cuộn cũ ---------------------------
   iPhone 390x844 khung nhìn thật chỉ ~700px, Android 360x640 chỉ ~510px.
   Ngưỡng cũ 430px gần như không bao giờ trúng -> body giữ overflow:hidden
   và dòng chú "Một số giá..." bị đè/mất như screenshot. Nâng lên 720px để
   bất kỳ máy dọc nào thiếu chiều cao đều được cuộn, chữ không bị cắt. */
@media (max-height: 720px) {
  body.la-app.man-1 {
    display: block; height: auto; overflow: visible;
    padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
  }
  body.la-app.man-1 .app-chan { position: fixed; }
  body.la-app.man-1 .app-bang1 { min-height: 74px; max-height: none; }
  body.la-app.man-1 .app-than { display: block; }
  body.la-app.man-1 .app-than > * + * { margin-top: 6px; }
  body.la-app.man-1 .app-muc-luoi { max-height: none; }
}

/* ==========================================================================
   CỬA HÀNG ONLINE (/cua-hang)
   Chỉ bố cục và khoảng cách. Màu lấy hết từ biến ở đầu tệp, không khai màu
   mới — chế độ Online đổi CHỮ, không đổi bảng màu.
   Tiền tố .la-cua-hang là class trên <main>, không phải trên <body>: khung
   chung ở phan.html phát ra <body> trần, không nơi nào gắn class vào nó.
   ========================================================================== */
/* Cột hẹp. Khung chung rộng 1240px là để xếp lưới nhiều cột; trang cửa hàng
   chỉ có MỘT cột, nên bỏ nguyên bề ngang ấy cho một ô nhập là bắt mắt chạy
   hết màn hình mới đọc lại được dòng vừa gõ. Chặn ở đây, không đụng .khung
   chung: class nằm trên <main> nên đầu trang và chân trang vẫn rộng như cũ. */
.la-cua-hang .khung { max-width: 820px; }

.la-cua-hang .ch-form { margin-top: 26px; }

.la-cua-hang .ch-o {
  margin: 0 0 22px; padding: 20px;
  border: 1px solid var(--vien); border-radius: var(--r-lon);
  background: var(--the);
}
/* Tiêu đề bước nằm HẲN trong thẻ, không cưỡi lên đường viền. Mặc định trình
   duyệt nhấc <legend> lên giữa nét viền trên: đường kẻ đâm ra hai bên chữ,
   dấu tiếng Việt chen với nét viền, cỡ 15px ở đó đọc chật. float:left +
   width:100% là cách duy nhất bắt legend hành xử như một khối thường — display
   block không ăn — và vì nó chiếm trọn bề ngang nên phần nội dung phía sau vẫn
   xuống dòng đúng chỗ. Viền fieldset nhờ vậy khép kín. */
.la-cua-hang .ch-o > legend,
.la-cua-hang .ch-o > h2 {
  margin: 0; padding: 0 0 12px;
  font: 700 16px/1.4 Roboto, system-ui, sans-serif; color: var(--muc);
}
.la-cua-hang .ch-o > legend { float: left; width: 100%; }
/* Legend đang float, mà .ch-mon là flex — flex tạo vùng định dạng riêng nên nó
   KHÔNG chui xuống dưới float, nó co lại nhường chỗ và hàng nút tròn bị đẩy
   dạt ra mép. clear trả mọi khối con về nguyên bề ngang, dưới legend. */
.la-cua-hang .ch-o > * { clear: both; }

.la-cua-hang .ch-mon { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 12px; }
.la-cua-hang .ch-mon label { display: flex; align-items: center; margin: 0; cursor: pointer; }

/* Nút tròn to hơn mặc định và ăn màu thương hiệu. Cỡ mặc định của trình duyệt
   là 13px xám nhạt — trên nền tím nó chìm, khách nhìn cả cột không biết mình
   đang tích cái nào. flex: none để nó không bị bóp khi tên món dài. */
.la-cua-hang .ch-mon input[type=radio],
.la-cua-hang .ch-goi input[type=radio] {
  flex: none; width: 18px; height: 18px; accent-color: var(--th);
}

/* Mỗi việc một thẻ bấm được cả ô, không bắt khách nhắm đúng cái nút tròn. */
.la-cua-hang .ch-goi-ds { display: grid; gap: 10px; margin-top: 14px; }
.la-cua-hang .ch-goi {
  display: flex; align-items: flex-start; gap: 12px; margin: 0;
  padding: 14px 16px;
  border: 1px solid var(--vien-dam); border-radius: var(--r-nho);
  background: var(--nen-2); cursor: pointer;
}
.la-cua-hang .ch-goi:hover { border-color: var(--sang); background: var(--th-nen); }
.la-cua-hang .ch-goi input { margin-top: 2px; }

/* Đã chọn thì CẢ THẺ phải đổi, không chỉ cái chấm tròn. Danh sách này dài
   chục dòng; nếu dấu hiệu duy nhất là chấm 18px thì khách phải rà mắt từ đầu
   xuống mới biết đã tích chưa, và trang xác nhận sẽ là chỗ đầu tiên họ biết
   mình chọn nhầm.
   Viền dày lên bằng box-shadow inset chứ không đổi border-width: đổi width là
   thẻ nhích 1px, cả cột giật khi bấm. */
.la-cua-hang .ch-goi:has(input:checked) {
  border-color: var(--th); background: var(--th-nen);
  box-shadow: inset 0 0 0 1px var(--th);
}
/* Bàn phím: viền focus phải thấy được cả khi thẻ chưa được chọn. */
.la-cua-hang .ch-goi:has(input:focus-visible) { outline: 2px solid var(--sang); outline-offset: 2px; }
.la-cua-hang .ch-goi input:focus-visible { outline: none; }
.la-cua-hang .ch-goi-than { display: grid; gap: 3px; }
.la-cua-hang .ch-goi-ten { font-weight: 600; }
.la-cua-hang .ch-goi-gia { font-size: 14px; color: var(--th); font-weight: 600; }
.la-cua-hang .ch-goi-dk { font-size: 13px; color: var(--muc-mo); }

.la-cua-hang .ch-nhac { margin-top: 14px; font-size: 13.5px; color: var(--muc-mo); }
.la-cua-hang .ch-nhac p { margin: 0 0 6px; }

.la-cua-hang .ch-loi {
  margin: 20px 0 0; padding: 12px 16px;
  border-left: 3px solid var(--tuchoi); border-radius: var(--r-nho);
  background: var(--nen-2); color: var(--muc); font-weight: 500;
}

/* --- Màn kết: mã đơn là thứ khách phải chép tay lên kiện hàng ---------- */
.la-cua-hang .ch-ma {
  margin: 26px 0; padding: 22px;
  border: 2px solid var(--th); border-radius: var(--r-lon);
  background: var(--th-nen); text-align: center;
}
.la-cua-hang .ch-ma-nhan {
  margin: 0; font: 600 12px/1.4 "Roboto Mono", monospace;
  letter-spacing: .12em; text-transform: uppercase; color: var(--muc-mo);
}
.la-cua-hang .ch-ma-so {
  margin: 8px 0 0;
  font: 700 34px/1.15 "Roboto Mono", monospace;
  letter-spacing: .06em; color: var(--muc);
  overflow-wrap: anywhere;
}
.la-cua-hang .ch-nut-chep { margin-top: 14px; }
.la-cua-hang .ch-ma .ch-nhac { text-align: left; }
.la-cua-hang .ch-dia-chi {
  margin: 0; font-size: 18px; font-weight: 600; color: var(--muc);
  overflow-wrap: anywhere;
}
.la-cua-hang .ch-gio { font-size: 14px; color: var(--muc-mo); }

@media (max-width: 560px) {
  .la-cua-hang .ch-o { padding: 16px; }
  .la-cua-hang .ch-ma-so { font-size: 27px; }
}
/* ---- KHỐI TRẢ TIỀN TRÊN TRANG TRA CỨU ---- */
/* Chỉ hiện khi đơn xong mà chưa thu đủ. Viền nhấn để khách không lướt qua
   mất — đây là ô duy nhất trên trang cần khách làm gì đó. */
.tra-tien { border-color: var(--vien-dam); }
.tra-tien h4 { margin-top: 18px; }
.tra-tien h4:first-of-type { margin-top: 14px; }
.tra-so { font-size: 28px; font-weight: 800; letter-spacing: -.02em; margin: 6px 0 0; }
.tra-tien p { margin: 8px 0 0; }
.tra-tien .bang td.p { font-variant-numeric: tabular-nums; }