/* generated by scripts/build.mjs from assets/fonts/v1/faces.css, css/v2/tokens.css, css/v2/base.css, css/v2/card.css, css/v2/panels.css, css/v2/dial.css, css/v2/project.css, css/v2/motion.css; edit those files */
@font-face{font-family:"LA Display";src:url("/assets/fonts/v1/orbitron-600.495f584f.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+20-5D, U+5F-7E, U+2013-2014, U+2018-2019, U+201C-201D, U+2026}
@font-face{font-family:"LA Display";src:url("/assets/fonts/v1/orbitron-700.33d606e0.woff2") format("woff2");font-weight:700;font-style:normal;font-display:swap;unicode-range:U+20-5D, U+5F-7E, U+2013-2014, U+2018-2019, U+201C-201D, U+2026}
@font-face{font-family:"LA Sans";src:url("/assets/fonts/v1/sans-400.9f11878e.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+20-7E, U+A0-FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2022, U+2026}
@font-face{font-family:"LA Sans";src:url("/assets/fonts/v1/sans-500.d899d683.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+20-7E, U+A0-FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2022, U+2026}
@font-face{font-family:"LA Sans";src:url("/assets/fonts/v1/sans-600.a014e85a.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+20-7E, U+A0-FF, U+2013-2014, U+2018-2019, U+201C-201D, U+2022, U+2026}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-400.266ee427.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+20, U+B7, U+2013-2014, U+3001-3002, U+300C-300F, U+301C, U+3042, U+3044, U+3046, U+304A-304D, U+304F, U+3051-3052, U+3054-3055, U+3057-3059, U+305B, U+305D, U+305F-3060, U+3063-3064, U+3066-306B, U+306E, U+3070, U+3073, U+3078, U+307B, U+307E-307F, U+3082, U+3088-308C, U+3092-3093, U+30A2-30A4, U+30A6-30AB, U+30AD, U+30AF-30B0, U+30B2-30B3, U+30B6-30BB, U+30BD, U+30BF-30C1, U+30C3-30C4, U+30C6-30C9, U+30CB, U+30CE, U+30D0, U+30D4-30D7, U+30DA, U+30DD, U+30DF-30E3, U+30E5, U+30E7, U+30E9-30ED, U+30F3, U+30FB-30FC, U+4E00, U+4E09-4E0A, U+4E2D, U+4E3B, U+4E88, U+4EBA, U+4ED6, U+4ED8, U+4F1A, U+4F38, U+4F5C, U+500B, U+502B, U+5148, U+516C, U+5185, U+518D, U+5192, U+5236, U+529B, U+529F, U+52D5, U+5316, U+53D6-53D7, U+5411, U+54C1, U+554F, U+56FD, U+5728, U+5883, U+58EB, U+5909, U+590F, U+5947, U+5999, U+5B63, U+5B66, U+5BFA, U+5C02, U+5C5E, U+5E33, U+5E38, U+5E74, U+5EB5, U+5F15, U+5F53, U+5F90, U+5FC3, U+5FDC, U+6210, U+6226, U+623B, U+6240, U+624B, U+629E, U+62C5, U+63CF, U+64CD, U+653B, U+65B0, U+65E5, U+666F, U+66A2, U+6700, U+6708, U+672C, U+6A21, U+6B74, U+6BCD, U+6CBF, U+6D41, U+6E08, U+706F, U+714C, U+73FE, U+7409, U+74B0, U+751F, U+7533, U+753B, U+767A, U+76F4, U+79FB, U+7B97, U+7CF8, U+7CFB, U+7D44, U+7D61, U+80CC, U+80FD, U+82F1, U+898B, U+898F, U+8A00, U+8A33, U+8A71, U+8A9E, U+8ABF, U+8CC7, U+8CDE, U+8EF8, U+9023, U+9054, U+9069, U+9078, U+90E8, U+91D1, U+958B, U+95A2, U+95D8, U+967A, U+984C, U+98A8, U+FF01, U+FF08-FF09, U+FF1A, U+FF1F}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-more-400.c7d6bf70.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+3000, U+3048, U+3050, U+3053, U+305A, U+305C, U+305E, U+3061, U+3065, U+306D, U+306F, U+3072, U+3079, U+3081, U+3083-3084, U+3086, U+308D, U+308F, U+30A1, U+30B1, U+30B4-30B5, U+30BE, U+30CA, U+30CD, U+30CF, U+30D1, U+30D3, U+30D9, U+30DB, U+30DE, U+30E4, U+30E6, U+30EF, U+4E0B, U+4E16, U+4E26, U+4E71, U+4E8B, U+4EA4, U+4ECA, U+4ED5, U+4EE3, U+4EE5, U+4EFB, U+4F3C, U+4F4D, U+4F53, U+4F55, U+4F59, U+4F7F, U+4FDD, U+4FE1, U+5024, U+50CF, U+5149, U+5165, U+5168, U+5177, U+51E6, U+51FA, U+5206-5207, U+5217, U+521D, U+5225, U+524D, U+5263, U+5272, U+52A0, U+52B1, U+52C9, U+52D9, U+5341, U+534A, U+5352, U+539F, U+53C2, U+53CB, U+53CE, U+53E3, U+53F0, U+5404, U+5408, U+540C, U+5426, U+5468, U+5473, U+547C, U+54E1, U+5584, U+55B6, U+565B, U+56DE, U+571F, U+578B, U+57FA, U+5834, U+58C1, U+58F0, U+58F2, U+5916, U+591C, U+5927, U+5968, U+5973, U+59CB, U+5B50, U+5B57-5B58, U+5B9A, U+5B9F, U+5BB6, U+5BB9, U+5BC4, U+5BC6, U+5BF8, U+5BFE, U+5C0E-5C0F, U+5C11, U+5C3E, U+5C4B, U+5C65, U+5CA9, U+5D29, U+5DE3, U+5DE5, U+5DE8, U+5E03, U+5E83, U+5EA6-5EA7, U+5EFA, U+5F0F, U+5F37, U+5F62, U+5F69, U+5F71, U+5F84, U+5F8C, U+5F93, U+5F97, U+5FA1, U+5FC5, U+6027, U+610F, U+61B6, U+6280, U+62B1, U+62BD, U+62D2, U+62EC, U+6301, U+6307, U+639B, U+63A1-63A2, U+63DB, U+63FA, U+640D, U+6539, U+6570, U+6574, U+6587, U+65AD, U+65B9, U+65BD, U+65CF, U+65E9, U+660E, U+6620, U+6642, U+6697, U+66F2, U+66F4, U+66F8, U+671F, U+6728, U+672B, U+6751, U+6761, U+679C, U+682A, U+683C, U+691C, U+696D, U+69CB, U+69D8, U+6A19, U+6A5F, U+6B21, U+6B62-6B63, U+6B8B, U+6BB5, U+6BCE, U+6BD4, U+6C17, U+6C34, U+6C7A, U+6CD5, U+6D17, U+6D1E, U+6DF1, U+6DF7, U+6E1B, U+6E2C, U+6E96, U+6F14, U+7070, U+708E, U+70B9, U+7167, U+7248, U+7269, U+72B6, U+72EC, U+7372, U+73A9, U+7406, U+7528, U+7531, U+7537, U+754C, U+7591, U+767B, U+767D, U+7684, U+76E4, U+76EE, U+7740, U+7814, U+793A, U+7981, U+79C1, U+79CB, U+79D1, U+7A0B, U+7A2E, U+7A76, U+7A7A, U+7A81, U+7A9F, U+7ACB, U+7AEF, U+7B2C, U+7B54, U+7B56, U+7BC9, U+7CBE, U+7D04, U+7D22, U+7D2B, U+7D30, U+7D42, U+7D4C, U+7D50, U+7D71, U+7D75, U+7D9A, U+7DD1-7DD2, U+7DDA, U+7DE8, U+7F6E, U+7F72, U+8003, U+81EA, U+821E, U+8272, U+8349, U+8377, U+843D, U+8679, U+884C, U+8853, U+8857, U+8868, U+88C5, U+88FD, U+8907, U+8981, U+8996, U+89A7, U+89E3, U+8A08, U+8A18, U+8A2D, U+8A3C, U+8A8C-8A8D, U+8AAD, U+8AB0, U+8AB2, U+8B58, U+8C61, U+8CA0, U+8CBB, U+8D64, U+8D77, U+8DA3, U+8DDD, U+8DEF, U+8EE2, U+8EFD, U+8F03, U+8F09, U+8F1D, U+8F2A, U+8FBC, U+8FD1, U+8FFD, U+9001, U+9003, U+9014, U+901A, U+9045, U+904A-904B, U+9055, U+90ED, U+914D, U+91CD, U+91CF, U+9332, U+9577, U+9593, U+95B2, U+968E, U+9694, U+96A3, U+96C6, U+96E2-96E3, U+9752, U+9759, U+9762, U+9805-9806, U+982D, U+985E, U+98DB, U+99AC, U+9AD8, U+9CE5, U+9EC4, U+9ED2}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-500.ecf1a969.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+20, U+B7, U+2013-2014, U+300C-300D, U+301C, U+3042, U+3046, U+304A-304C, U+304F, U+3051-3052, U+3054-3055, U+3058, U+305B, U+305D, U+305F-3060, U+3063-3064, U+3068-306A, U+3070, U+3073, U+307B, U+307F, U+3082, U+3088-308A, U+308C, U+3093, U+30B0, U+30BB, U+30CE, U+30D4, U+30DF, U+30E5, U+30E7, U+4E00, U+4E09-4E0A, U+4E2D, U+4E3B, U+4E88, U+4EBA, U+4ED6, U+4ED8, U+4F1A, U+4F38, U+500B, U+502B, U+5148, U+5185, U+518D, U+5192, U+529B, U+529F, U+52D5, U+5316, U+53D6-53D7, U+5411, U+54C1, U+554F, U+56FD, U+5728, U+5883, U+5909, U+590F, U+5947, U+5999, U+5B63, U+5BFA, U+5C5E, U+5E33, U+5E38, U+5E74, U+5EB5, U+5F15, U+5F53, U+5F90, U+5FC3, U+5FDC, U+6210, U+6226, U+6240, U+624B, U+629E, U+62C5, U+63CF, U+64CD, U+65E5, U+666F, U+66A2, U+6700, U+6708, U+672C, U+6A21, U+6B74, U+6BCD, U+6CBF, U+6D41, U+6E08, U+706F, U+714C, U+73FE, U+7409, U+74B0, U+751F, U+7533, U+753B, U+76F4, U+79FB, U+7B97, U+7CF8, U+7CFB, U+7D44, U+7D61, U+80CC, U+80FD, U+82F1, U+898B, U+898F, U+8A00, U+8A33, U+8A71, U+8A9E, U+8ABF, U+8CC7, U+8CDE, U+8EF8, U+9023, U+9054, U+9069, U+9078, U+90E8, U+91D1, U+95A2, U+95D8, U+967A, U+984C, U+98A8, U+FF01, U+FF1F}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-more-500.3d167070.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+3000, U+3048, U+3050, U+3053, U+305A, U+305C, U+305E, U+3061, U+3065, U+306D, U+306F, U+3072, U+3079, U+3081, U+3083-3084, U+3086, U+308D, U+308F, U+30A1, U+30B1, U+30B4, U+30BE, U+30CD, U+30CF, U+30D1, U+30D3, U+30D9, U+30DB, U+30DE, U+30E4, U+30E6, U+30EF, U+4E0B, U+4E16, U+4E26, U+4E71, U+4E8B, U+4EA4, U+4ECA, U+4ED5, U+4EE3, U+4EE5, U+4EFB, U+4F3C, U+4F4D, U+4F53, U+4F55, U+4F59, U+4F7F, U+4FDD, U+4FE1, U+5024, U+50CF, U+5149, U+5165, U+5168, U+5177, U+51E6, U+51FA, U+5206-5207, U+5217, U+521D, U+5225, U+524D, U+5263, U+5272, U+52A0, U+52B1, U+52C9, U+52D9, U+5341, U+534A, U+5352, U+539F, U+53C2, U+53CB, U+53CE, U+53E3, U+53F0, U+5404, U+5408, U+540C, U+5426, U+5468, U+5473, U+547C, U+54E1, U+5584, U+55B6, U+565B, U+56DE, U+571F, U+578B, U+57FA, U+5834, U+58C1, U+58F0, U+58F2, U+5916, U+591C, U+5927, U+5968, U+5973, U+59CB, U+5B50, U+5B57-5B58, U+5B9A, U+5B9F, U+5BB6, U+5BB9, U+5BC4, U+5BC6, U+5BF8, U+5BFE, U+5C0E-5C0F, U+5C11, U+5C3E, U+5C4B, U+5C65, U+5CA9, U+5D29, U+5DE3, U+5DE5, U+5DE8, U+5E03, U+5E83, U+5EA6-5EA7, U+5EFA, U+5F37, U+5F62, U+5F69, U+5F71, U+5F84, U+5F8C, U+5F93, U+5F97, U+5FA1, U+5FC5, U+6027, U+610F, U+61B6, U+6280, U+62B1, U+62BD, U+62D2, U+62EC, U+6301, U+6307, U+639B, U+63A1-63A2, U+63DB, U+63FA, U+640D, U+6539, U+6570, U+6574, U+6587, U+65AD, U+65B9, U+65BD, U+65CF, U+65E9, U+660E, U+6620, U+6642, U+6697, U+66F2, U+66F4, U+66F8, U+671F, U+6728, U+672B, U+6751, U+6761, U+679C, U+682A, U+683C, U+691C, U+696D, U+69CB, U+69D8, U+6A19, U+6A5F, U+6B21, U+6B62-6B63, U+6B8B, U+6BB5, U+6BCE, U+6BD4, U+6C17, U+6C34, U+6C7A, U+6CD5, U+6D17, U+6D1E, U+6DF1, U+6DF7, U+6E1B, U+6E2C, U+6E96, U+6F14, U+7070, U+708E, U+70B9, U+7167, U+7248, U+7269, U+72B6, U+72EC, U+7372, U+73A9, U+7406, U+7528, U+7531, U+7537, U+754C, U+7591, U+767B, U+767D, U+7684, U+76E4, U+76EE, U+7740, U+7814, U+793A, U+7981, U+79C1, U+79CB, U+79D1, U+7A0B, U+7A2E, U+7A76, U+7A7A, U+7A81, U+7A9F, U+7ACB, U+7AEF, U+7B2C, U+7B54, U+7B56, U+7BC9, U+7CBE, U+7D04, U+7D22, U+7D2B, U+7D30, U+7D42, U+7D4C, U+7D50, U+7D71, U+7D75, U+7D9A, U+7DD1-7DD2, U+7DDA, U+7DE8, U+7F6E, U+7F72, U+8003, U+81EA, U+821E, U+8272, U+8349, U+8377, U+843D, U+8679, U+884C, U+8853, U+8857, U+8868, U+88C5, U+88FD, U+8907, U+8981, U+8996, U+89A7, U+89E3, U+8A08, U+8A18, U+8A2D, U+8A3C, U+8A8C-8A8D, U+8AAD, U+8AB0, U+8AB2, U+8B58, U+8C61, U+8CA0, U+8CBB, U+8D64, U+8D77, U+8DA3, U+8DDD, U+8DEF, U+8EE2, U+8EFD, U+8F03, U+8F09, U+8F1D, U+8F2A, U+8FBC, U+8FD1, U+8FFD, U+9001, U+9003, U+9014, U+901A, U+9045, U+904A-904B, U+9055, U+90ED, U+914D, U+91CD, U+91CF, U+9332, U+9577, U+9593, U+95B2, U+968E, U+9694, U+96A3, U+96C6, U+96E2-96E3, U+9752, U+9759, U+9762, U+9805-9806, U+982D, U+985E, U+98DB, U+99AC, U+9AD8, U+9CE5, U+9EC4, U+9ED2}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-600.241ce2d5.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+B7, U+2013-2014, U+3001-3002, U+300C-300F, U+301C, U+304B-304D, U+3051-3052, U+3055, U+3059, U+305B, U+3060, U+3063, U+3067, U+3069-306A, U+3070, U+3073, U+3078, U+307B, U+307E, U+3082, U+3088-3089, U+308B-308C, U+3092, U+30B6, U+30BB, U+30C9, U+30CB, U+30D6, U+30DA, U+30DD, U+30DF, U+30E7, U+30E9, U+4E00, U+4E0A, U+4E2D, U+4E3B, U+4E88, U+4EBA, U+4ED8, U+4F1A, U+4F38, U+500B, U+5148, U+516C, U+5185, U+518D, U+5192, U+5236, U+529B, U+529F, U+52D5, U+5316, U+53D6, U+5411, U+554F, U+56FD, U+5728, U+5883, U+58EB, U+5909, U+590F, U+5947, U+5999, U+5B63, U+5B66, U+5C02, U+5C5E, U+5E38, U+5E74, U+5F15, U+5FC3, U+5FDC, U+6210, U+6226, U+623B, U+6240, U+624B, U+629E, U+63CF, U+64CD, U+653B, U+65B0, U+65E5, U+666F, U+66A2, U+6700, U+6708, U+672C, U+6A21, U+6B74, U+6BCD, U+6CBF, U+6D41, U+74B0, U+751F, U+7533, U+753B, U+767A, U+76F4, U+79FB, U+7B97, U+7CFB, U+7D44, U+7D61, U+80CC, U+80FD, U+82F1, U+898B, U+898F, U+8A00, U+8A33, U+8A71, U+8A9E, U+8EF8, U+9023, U+9054, U+9069, U+9078, U+90E8, U+958B, U+95A2, U+95D8, U+967A, U+98A8, U+FF01, U+FF1F}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-more-600.b24f10e5.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+3000, U+3048, U+3050, U+305A, U+305C, U+305E, U+3061, U+3065, U+306D, U+306F, U+3072, U+3079, U+3081, U+3083-3084, U+3086, U+308D, U+308F, U+30A1, U+30B1, U+30B4, U+30BE, U+30CA, U+30CD, U+30CF, U+30D1, U+30D3, U+30D9, U+30DB, U+30DE, U+30E4, U+30E6, U+30EF, U+4E0B, U+4E16, U+4E26, U+4E71, U+4E8B, U+4EA4, U+4ED5, U+4EE3, U+4EE5, U+4EFB, U+4F3C, U+4F4D, U+4F53, U+4F55, U+4F59, U+4FDD, U+4FE1, U+5024, U+50CF, U+5149, U+5165, U+5168, U+5177, U+51E6, U+51FA, U+5206-5207, U+5217, U+521D, U+5225, U+524D, U+5272, U+52A0, U+52B1, U+52C9, U+52D9, U+5341, U+534A, U+5352, U+539F, U+53C2, U+53CB, U+53CE, U+53E3, U+53F0, U+5404, U+5408, U+540C, U+5426, U+5468, U+5473, U+547C, U+54E1, U+55B6, U+565B, U+56DE, U+571F, U+578B, U+57FA, U+5834, U+58C1, U+58F0, U+58F2, U+5916, U+591C, U+5927, U+5968, U+5973, U+59CB, U+5B58, U+5B9A, U+5B9F, U+5BB6, U+5BB9, U+5BC4, U+5BC6, U+5BF8, U+5BFE, U+5C0E-5C0F, U+5C11, U+5C3E, U+5C4B, U+5C65, U+5CA9, U+5D29, U+5DE3, U+5DE5, U+5DE8, U+5E03, U+5E83, U+5EA6-5EA7, U+5EFA, U+5F0F, U+5F37, U+5F62, U+5F69, U+5F71, U+5F84, U+5F93, U+5F97, U+5FA1, U+5FC5, U+6027, U+610F, U+61B6, U+6280, U+62B1, U+62BD, U+62D2, U+62EC, U+6301, U+6307, U+639B, U+63A1-63A2, U+63DB, U+63FA, U+640D, U+6570, U+6587, U+65AD, U+65BD, U+65CF, U+65E9, U+6620, U+6642, U+66F2, U+66F4, U+66F8, U+671F, U+6728, U+672B, U+6751, U+6761, U+679C, U+682A, U+683C, U+691C, U+696D, U+69CB, U+69D8, U+6A19, U+6A5F, U+6B21, U+6B62-6B63, U+6B8B, U+6BB5, U+6BCE, U+6BD4, U+6C17, U+6C34, U+6C7A, U+6CD5, U+6D17, U+6D1E, U+6DF1, U+6DF7, U+6E1B, U+6E2C, U+6E96, U+6F14, U+7070, U+708E, U+7167, U+7248, U+7269, U+72EC, U+7372, U+73A9, U+7406, U+7531, U+7537, U+754C, U+7591, U+767B, U+767D, U+7684, U+76E4, U+7740, U+7814, U+793A, U+7981, U+79C1, U+79CB, U+79D1, U+7A0B, U+7A2E, U+7A76, U+7A7A, U+7A81, U+7A9F, U+7ACB, U+7AEF, U+7B2C, U+7B54, U+7B56, U+7BC9, U+7CBE, U+7D04, U+7D22, U+7D2B, U+7D30, U+7D42, U+7D4C, U+7D50, U+7D71, U+7D75, U+7D9A, U+7DD1-7DD2, U+7DE8, U+7F6E, U+7F72, U+8003, U+81EA, U+821E, U+8377, U+843D, U+8679, U+884C, U+8853, U+8857, U+8868, U+88C5, U+88FD, U+8907, U+8981, U+8996, U+89A7, U+89E3, U+8A08, U+8A18, U+8A2D, U+8A3C, U+8A8C-8A8D, U+8AAD, U+8AB0, U+8B58, U+8C61, U+8CA0, U+8CBB, U+8D64, U+8D77, U+8DA3, U+8DDD, U+8DEF, U+8EE2, U+8EFD, U+8F03, U+8F09, U+8F1D, U+8FBC, U+8FD1, U+8FFD, U+9001, U+9003, U+9014, U+901A, U+9045, U+904A-904B, U+9055, U+914D, U+91CD, U+91CF, U+9332, U+9577, U+9593, U+95B2, U+968E, U+9694, U+96A3, U+96C6, U+96E2-96E3, U+9752, U+9759, U+9762, U+9806, U+982D, U+985E, U+98DB, U+99AC, U+9AD8, U+9CE5, U+9EC4, U+9ED2}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-400.4d9c84de.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+20, U+B7, U+2013-2014, U+3001-3002, U+300A-300D, U+4E00, U+4E09, U+4E0E, U+4E13, U+4E1D, U+4E2A, U+4E2D, U+4E3B, U+4E4B, U+4E60, U+4E86, U+4E8E, U+4E9A, U+4EA7, U+4EBA, U+4ECA, U+4ECE, U+4ED6, U+4EE5, U+4F17-4F18, U+4F1A, U+4F26, U+4F55, U+4F5C, U+4F7F, U+4F9B, U+505A, U+5173, U+5176-5177, U+517C, U+5185, U+5192, U+51E0, U+51EF, U+51FA, U+5206-5207, U+5229, U+5230, U+5236, U+524D, U+529B, U+529F, U+52A8, U+5316, U+5347, U+5361, U+5386, U+539F, U+53C2, U+53CA, U+53D1, U+540E, U+5458, U+54C1, U+5668, U+56DE, U+56E2, U+5728, U+5730, U+573A, U+5740, U+5883, U+58EB, U+5904, U+590D, U+5927, U+5934, U+5947, U+5956, U+5999, U+59C6, U+5B66, U+5B83, U+5B9E, U+5BB9, U+5C14, U+5C31, U+5DE5, U+5DF2, U+5E08, U+5E26-5E27, U+5E38, U+5E74, U+5E76, U+5E8F, U+5E94, U+5EB5, U+5F00, U+5F0F, U+5F90, U+5F97, U+5FC3, U+60AC, U+620F-6211, U+6218, U+624B, U+6253, U+627E, U+6280, U+628A, U+62B1, U+62DF, U+63A7, U+63D0, U+6548, U+6559, U+6570, U+6587, U+6597, U+65AF-65B0, U+65B9, U+65E5, U+65F6, U+661F, U+662F, U+666F, U+6691, U+66F2, U+6708, U+671F, U+672A, U+672F, U+673A, U+6761, U+679C, U+6807, U+6838, U+683C, U+6A21, U+6B3E, U+6B49, U+6B65, U+6BCD, U+6CBF, U+6CE8, U+6D41, U+6E38, U+70B9, U+714C, U+7279, U+7387, U+73AF-73B0, U+7403, U+7406, U+7409, U+751F, U+7528, U+753B, U+7591, U+767B, U+767E, U+7684, U+76EE, U+7740, U+7814, U+78E8, U+79FB, U+7A0B, U+7B79, U+7B7E, U+7B80, U+7B97, U+7BB1, U+7C73, U+7CFB, U+7EBF, U+7ED8, U+7EDD, U+7EDF, U+7F57, U+7F8E, U+8054, U+80B2, U+80CC, U+80FD, U+81EA, U+81F3, U+8272, U+8282, U+82F1, U+83B7, U+8482, U+8981, U+8A00, U+8BA1, U+8BBE, U+8BDD, U+8BED, U+8BF7, U+8D1F, U+8D23, U+8D44, U+8D77, U+8DF3, U+8FD4, U+8FD9, U+9002, U+9009, U+90AE, U+90E8, U+91CD, U+955C, U+95EE, U+961F, U+963F, U+9646, U+9662, U+9669, U+968F, U+96C6, U+9762, U+9875, U+9879, U+987E, U+9884, U+9898, U+98CE, U+9996, U+FF01, U+FF08-FF09, U+FF0C, U+FF1A-FF1B, U+FF1F}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-more-400.5a804278.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+201C-201D, U+3000, U+4E03, U+4E07, U+4E0A-4E0B, U+4E0D, U+4E14, U+4E16, U+4E1A, U+4E22, U+4E24, U+4E3A, U+4E45, U+4E48-4E49, U+4E50, U+4E58, U+4E5F, U+4E8B-4E8C, U+4E92, U+4E94, U+4E9B, U+4EAB, U+4EAE, U+4EC0, U+4EC5, U+4ECD, U+4EE3-4EE4, U+4EEC, U+4EF6, U+4EFB, U+4EFD, U+4F2A, U+4F46, U+4F4D, U+4F4F, U+4F53, U+4F59, U+4F73, U+4F9D, U+4FBF, U+4FDD, U+503C, U+504F, U+505C, U+50CF, U+513F, U+5143, U+5148-5149, U+5165, U+5168, U+516C-516D, U+5171, U+518D, U+5199, U+51B3, U+51C0, U+51C6, U+51FD, U+5212, U+5217, U+5219, U+521D, U+522B, U+5251, U+529E, U+52A0, U+52A9, U+52BF, U+5305, U+5339, U+534A, U+5373, U+5385, U+538B, U+53BB, U+53C8, U+53CB-53CC, U+53D6-53D8, U+53E0, U+53EA, U+53EF-53F0, U+53F7, U+5408, U+540C-540D, U+5411, U+5448, U+544A, U+548C, U+552E, U+559C, U+566A, U+56DB, U+56E0, U+56FE, U+571F, U+5750, U+5757, U+575A, U+578B, U+57FA, U+5802, U+585E, U+5899, U+58C1, U+58F0, U+590F, U+5916, U+591A, U+591C, U+591F, U+5929-592A, U+5973, U+597D, U+5982, U+59FF, U+5A74, U+5A92, U+5B50, U+5B57-5B58, U+5B63, U+5B69, U+5B88, U+5B8C, U+5B98, U+5B9A, U+5BA2, U+5BA4, U+5BB6, U+5BC6, U+5BF8-5BF9, U+5BFC, U+5C01, U+5C04, U+5C0F, U+5C3A, U+5C40, U+5C42, U+5C4B, U+5C4F, U+5C55, U+5CA9, U+5D4C, U+5DE2, U+5DE8, U+5DF1, U+5E03, U+5E55, U+5E72-5E73, U+5E78, U+5E84, U+5EA6-5EA7, U+5EAD, U+5EFA, U+5F20, U+5F2F, U+5F53, U+5F55, U+5F62, U+5F69, U+5F71, U+5F79, U+5F84, U+5F88, U+5FAA, U+5FAE, U+5FC5-5FC6, U+5FD7, U+6001, U+600E, U+6027, U+602A, U+60F3, U+610F, U+611F, U+6162, U+6216, U+622A, U+623F-6240, U+626E, U+6279, U+6296, U+62A2, U+62A4, U+62AC, U+62BD, U+62C5-62C6, U+62CD, U+62D2, U+62D6, U+62DB-62DC, U+62FF, U+6301, U+6309, U+632A, U+6362, U+636E, U+6389, U+6392, U+63A5, U+63A8, U+63CF, U+641C, U+642D, U+6446-6447, U+6491, U+64B0, U+652F, U+6539, U+653B, U+653E, U+6545, U+6574, U+65AD, U+65BD, U+65C1, U+65CB, U+65E0, U+65E2, U+660E, U+6620, U+665A, U+6670, U+6697, U+66F4, U+66FF-6700, U+6709, U+670B, U+671D, U+6728, U+672B-672C, U+6750-6751, U+675F, U+6765, U+677F, U+6784, U+67E5, U+6811, U+6837, U+6839, U+6846, U+6848, U+6863, U+6869, U+68C0, U+6982, U+6B21-6B22, U+6B4C, U+6B62-6B63, U+6B66, U+6BB5, U+6BCF, U+6BD4-6BD5, U+6C42, U+6C99, U+6CA1, U+6CD5, U+6CE2, U+6CE5, U+6CF0, U+6D1E, U+6D4B, U+6D77, U+6D82, U+6D88, U+6DE1, U+6DF1, U+6DF7, U+6E05, U+6E10, U+6E90, U+6EB6, U+6EE1, U+6EE4, U+6F0F, U+6F14, U+706B, U+7070, U+7075, U+7130, U+7136, U+7167, U+718A, U+7247-7248, U+7269, U+72B6, U+72EC, U+73A9, U+7531, U+7537, U+754C, U+7559, U+767D, U+76D6, U+76F4, U+76F8, U+7701, U+770B, U+77E9, U+77F3, U+7801, U+7834, U+786E, U+793A, U+7981, U+79BB, U+79CB, U+79CD, U+79EF, U+7A3F, U+7A74, U+7A76, U+7A7A, U+7A81, U+7ACB, U+7AD9, U+7ADF, U+7AEF, U+7B14, U+7B2C, U+7B49, U+7BA1, U+7C7B, U+7CBE, U+7D20, U+7D22, U+7D2B, U+7EA2, U+7EA6-7EA7, U+7EB9, U+7EC6, U+7EC8, U+7ED3, U+7ED5, U+7ED9, U+7EED, U+7EF4, U+7EFF, U+7F16, U+7F18, U+7F29, U+7F51, U+7F6E, U+8005, U+800C, U+8017, U+8033, U+804C, U+811A, U+81F4, U+82B1, U+8349, U+83C7, U+8424, U+843D, U+84DD, U+8611, U+866B, U+8679, U+86D9, U+884C, U+8857, U+8868, U+88AB, U+89C2, U+89C4, U+89C6, U+89C9, U+89D2, U+89E3, U+8BA4, U+8BA9, U+8BB0, U+8BB2, U+8BBA, U+8BBF, U+8BC1, U+8BCD, U+8BD5, U+8BE5, U+8BFB, U+8C03, U+8C22, U+8C61, U+8D1D, U+8D28, U+8D62, U+8D70, U+8D85, U+8DB3, U+8DC3, U+8DD1, U+8DDD, U+8DDF, U+8EAB, U+8F6C, U+8F6F, U+8F7B, U+8F7D, U+8F83, U+8F91, U+8F93, U+8FA8, U+8FB9, U+8FC7, U+8FD1, U+8FD8, U+8FDB-8FDC, U+8FDE, U+8FEA, U+8FF0, U+8FF7, U+8FFD, U+9010, U+901A, U+9020, U+9053, U+9063, U+9075, U+90A3, U+90FD, U+914D, U+91C7, U+91CC, U+91CF, U+91D1, U+9488, U+9500, U+957F, U+95E8, U+95F4, U+9634-9636, U+9650, U+9664, U+9668, U+96BE, U+9700, U+9752, U+9759, U+9760, U+987B, U+9891, U+989C, U+98DE, U+9971, U+9A6C, U+9A71, U+9A8C, U+9AA4, U+9AD8, U+9B42, U+9E1F, U+9E26, U+9EC4, U+9ED1}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-500.98796e4f.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+20, U+2013-2014, U+3001, U+300C-300D, U+4E00, U+4E09, U+4E13, U+4E1D, U+4E2A, U+4E2D, U+4E4B, U+4E60, U+4E86, U+4E8E, U+4E9A, U+4EA7, U+4EBA, U+4ECA, U+4ECE, U+4ED6, U+4EE5, U+4F17-4F18, U+4F1A, U+4F26, U+4F55, U+4F7F, U+4F9B, U+505A, U+5173, U+5176-5177, U+517C, U+5192, U+51E0, U+51EF, U+51FA, U+5206-5207, U+5229, U+524D, U+529B, U+529F, U+52A8, U+5316, U+5347, U+5361, U+5386, U+539F, U+53C2, U+53CA, U+540E, U+5458, U+5668, U+573A, U+5740, U+5883, U+5904, U+590D, U+5934, U+5947, U+5956, U+5999, U+59C6, U+5B83, U+5C14, U+5C31, U+5DE5, U+5DF2, U+5E26-5E27, U+5E38, U+5E74, U+5E76, U+5E8F, U+5E94, U+5EB5, U+5F0F, U+5F90, U+5F97, U+5FC3, U+60AC, U+6210, U+624B, U+627E, U+628A, U+62B1, U+62DF, U+63A7, U+63D0, U+6559, U+6570, U+6587, U+6597, U+65AF, U+65E5, U+662F, U+666F, U+6691, U+66F2, U+6708, U+671F, U+672A, U+673A, U+6761, U+679C, U+6838, U+683C, U+6A21, U+6B3E, U+6B49, U+6B65, U+6BCD, U+6CBF, U+6CE8, U+6D41, U+70B9, U+714C, U+7387, U+73AF-73B0, U+7406, U+7409, U+751F, U+7528, U+753B, U+7591, U+767B, U+767E, U+76EE, U+7740, U+7814, U+78E8, U+79FB, U+7A0B, U+7B79, U+7B80, U+7B97, U+7C73, U+7CFB, U+7EBF, U+7ED8, U+7EDF, U+7F57, U+8054, U+80B2, U+80CC, U+80FD, U+81EA, U+81F3, U+8272, U+8282, U+82F1, U+83B7, U+8482, U+8A00, U+8BDD, U+8BED, U+8BF7, U+8D1F, U+8D23, U+8D44, U+8D77, U+8FD9, U+9002, U+9009, U+90E8, U+91CD, U+955C, U+95EE, U+963F, U+9646, U+9662, U+9669, U+968F, U+9879, U+987E, U+9898, U+98CE, U+9996, U+FF01, U+FF1B, U+FF1F}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-more-500.b3a9c598.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+201C-201D, U+3000, U+4E03, U+4E07, U+4E0A, U+4E0D, U+4E14, U+4E16, U+4E1A, U+4E22, U+4E24, U+4E3A, U+4E45, U+4E48-4E49, U+4E50, U+4E58, U+4E5F, U+4E8B-4E8C, U+4E92, U+4E94, U+4E9B, U+4EAB, U+4EAE, U+4EC0, U+4EC5, U+4ECD, U+4EE3-4EE4, U+4EEC, U+4EF6, U+4EFB, U+4EFD, U+4F2A, U+4F46, U+4F4D, U+4F4F, U+4F53, U+4F59, U+4F73, U+4F9D, U+4FBF, U+4FDD, U+503C, U+504F, U+505C, U+50CF, U+513F, U+5143, U+5148-5149, U+5165, U+5168, U+516C-516D, U+5171, U+518D, U+5199, U+51B3, U+51C0, U+51C6, U+51FD, U+5212, U+5217, U+5219, U+521D, U+522B, U+5251, U+529E, U+52A0, U+52A9, U+52BF, U+5305, U+5339, U+534A, U+5373, U+5385, U+538B, U+53BB, U+53C8, U+53CB-53CC, U+53D6-53D8, U+53E0, U+53EA, U+53EF-53F0, U+53F7, U+5408, U+540C-540D, U+5411, U+5448, U+548C, U+552E, U+559C, U+566A, U+56DB, U+56E0, U+56FE, U+571F, U+5750, U+5757, U+575A, U+578B, U+57FA, U+5802, U+585E, U+5899, U+58C1, U+58F0, U+590F, U+5916, U+591A, U+591C, U+591F, U+5929-592A, U+5973, U+597D, U+5982, U+59FF, U+5A74, U+5A92, U+5B50, U+5B57, U+5B63, U+5B69, U+5B88, U+5B8C, U+5B9A, U+5BA2, U+5BA4, U+5BB6, U+5BC6, U+5BF8-5BF9, U+5BFC, U+5C01, U+5C04, U+5C0F, U+5C3A, U+5C40, U+5C42, U+5C4B, U+5C4F, U+5C55, U+5CA9, U+5D4C, U+5DE2, U+5DE8, U+5DF1, U+5E03, U+5E55, U+5E72-5E73, U+5E84, U+5EA6-5EA7, U+5EAD, U+5EFA, U+5F20, U+5F2F, U+5F53, U+5F55, U+5F62, U+5F69, U+5F71, U+5F79, U+5F84, U+5F88, U+5FAA, U+5FAE, U+5FC5-5FC6, U+6001, U+600E, U+6027, U+602A, U+60F3, U+610F, U+611F, U+6162, U+6216, U+622A, U+623F-6240, U+626E, U+6279, U+6296, U+62A2, U+62A4, U+62AC, U+62BD, U+62C5-62C6, U+62CD, U+62D2, U+62D6, U+62DB-62DC, U+62FF, U+6301, U+6309, U+632A, U+6362, U+636E, U+6389, U+6392, U+63A5, U+63A8, U+63CF, U+641C, U+642D, U+6446-6447, U+6491, U+64B0, U+652F, U+6539, U+653B, U+653E, U+6545, U+6574, U+65AD, U+65BD, U+65C1, U+65CB, U+65E0, U+65E2, U+660E, U+6620, U+665A, U+6670, U+6697, U+66F4, U+66FF-6700, U+6709, U+670B, U+671D, U+6728, U+672B-672C, U+6750-6751, U+675F, U+6765, U+677F, U+6784, U+67E5, U+6811, U+6837, U+6839, U+6846, U+6848, U+6863, U+6869, U+68C0, U+6982, U+6B21-6B22, U+6B4C, U+6B62-6B63, U+6BB5, U+6BCF, U+6BD4-6BD5, U+6C42, U+6C99, U+6CA1, U+6CD5, U+6CE2, U+6CE5, U+6CF0, U+6D1E, U+6D4B, U+6D77, U+6D82, U+6D88, U+6DE1, U+6DF1, U+6DF7, U+6E05, U+6E10, U+6E90, U+6EB6, U+6EE1, U+6EE4, U+6F0F, U+6F14, U+706B, U+7070, U+7075, U+7130, U+7136, U+7167, U+718A, U+7269, U+72B6, U+72EC, U+7531, U+7537, U+754C, U+7559, U+767D, U+76D6, U+76F4, U+76F8, U+7701, U+770B, U+77E9, U+77F3, U+7801, U+7834, U+786E, U+793A, U+7981, U+79BB, U+79CB, U+79CD, U+79EF, U+7A3F, U+7A74, U+7A76, U+7A7A, U+7A81, U+7ACB, U+7ADF, U+7AEF, U+7B14, U+7B2C, U+7B49, U+7BA1, U+7C7B, U+7CBE, U+7D20, U+7D22, U+7D2B, U+7EA2, U+7EA6-7EA7, U+7EB9, U+7EC6, U+7EC8, U+7ED3, U+7ED5, U+7ED9, U+7EED, U+7EF4, U+7EFF, U+7F16, U+7F18, U+7F29, U+7F6E, U+800C, U+8017, U+8033, U+804C, U+811A, U+81F4, U+82B1, U+8349, U+83C7, U+8424, U+84DD, U+8611, U+866B, U+8679, U+86D9, U+884C, U+8857, U+8868, U+88AB, U+89C2, U+89C4, U+89C6, U+89C9, U+89D2, U+89E3, U+8BA4, U+8BA9, U+8BB0, U+8BB2, U+8BBA, U+8BBF, U+8BC1, U+8BCD, U+8BE5, U+8BFB, U+8C03, U+8C22, U+8C61, U+8D1D, U+8D28, U+8D62, U+8D70, U+8D85, U+8DB3, U+8DC3, U+8DD1, U+8DDD, U+8DDF, U+8EAB, U+8F6C, U+8F6F, U+8F7B, U+8F83, U+8F91, U+8F93, U+8FA8, U+8FB9, U+8FC7, U+8FD1, U+8FD8, U+8FDB-8FDC, U+8FDE, U+8FEA, U+8FF0, U+8FF7, U+8FFD, U+9010, U+901A, U+9020, U+9053, U+9063, U+9075, U+90A3, U+90FD, U+914D, U+91C7, U+91CC, U+91CF, U+91D1, U+9488, U+9500, U+957F, U+95E8, U+95F4, U+9634-9636, U+9650, U+9664, U+96BE, U+9700, U+9752, U+9759, U+9760, U+987B, U+9891, U+989C, U+98DE, U+9971, U+9A6C, U+9A71, U+9A8C, U+9AA4, U+9AD8, U+9B42, U+9E1F, U+9E26, U+9EC4, U+9ED1}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-600.59df2517.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+2013-2014, U+3001-3002, U+300A-300D, U+4E09, U+4E13, U+4E2A, U+4E2D, U+4E3B, U+4E9A, U+4EA7, U+4EBA, U+4ECA, U+4ECE, U+4EE5, U+4F17-4F18, U+4F1A, U+4F55, U+4F9B, U+517C, U+5185, U+5192, U+51E0, U+51EF, U+51FA, U+5206-5207, U+5229, U+5230, U+524D, U+529B, U+529F, U+52A8, U+5316, U+5347, U+5361, U+539F, U+53CA, U+53D1, U+5458, U+56DE, U+5728, U+573A, U+5740, U+5883, U+5904, U+5934, U+5947, U+5999, U+59C6, U+5B66, U+5B83, U+5BB9, U+5C14, U+5C31, U+5E08, U+5E26-5E27, U+5E38, U+5E74, U+5E76, U+5E8F, U+5E94, U+5F00, U+5F0F, U+5F97, U+5FC3, U+60AC, U+6210, U+624B, U+6253, U+627E, U+6280, U+628A, U+62B1, U+62DF, U+63A7, U+63D0, U+6559, U+6587, U+6597, U+65AF-65B0, U+65E5, U+65F6, U+662F, U+666F, U+6691, U+66F2, U+6708, U+671F, U+672A, U+672F, U+673A, U+6761, U+679C, U+6807, U+6838, U+683C, U+6A21, U+6B3E, U+6B49, U+6BCD, U+6CBF, U+6CE8, U+6D41, U+70B9, U+7387, U+73AF, U+753B, U+7591, U+767B, U+767E, U+76EE, U+7814, U+78E8, U+79FB, U+7A0B, U+7B79, U+7B7E, U+7B97, U+7BB1, U+7C73, U+7ED8, U+7EDF, U+7F57, U+7F8E, U+8054, U+80B2, U+80CC, U+80FD, U+81EA, U+81F3, U+8282, U+82F1, U+83B7, U+8482, U+8981, U+8A00, U+8BA1, U+8BBE, U+8BDD, U+8BED, U+8BF7, U+8D1F, U+8D23, U+8D77, U+8DF3, U+8FD4, U+8FD9, U+9002, U+9009, U+90AE, U+90E8, U+91CD, U+955C, U+95EE, U+961F, U+963F, U+9646, U+9662, U+9669, U+968F, U+96C6, U+9762, U+9875, U+987E, U+9884, U+9898, U+98CE, U+9996, U+FF01, U+FF0C, U+FF1B, U+FF1F}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-more-600.ba930705.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+D7, U+E9, U+201C-201D, U+3000, U+4E03, U+4E07, U+4E0A, U+4E0D, U+4E14, U+4E16, U+4E1A, U+4E22, U+4E24, U+4E3A, U+4E45, U+4E49, U+4E50, U+4E58, U+4E5F, U+4E8B-4E8C, U+4E92, U+4E94, U+4E9B, U+4EAB, U+4EAE, U+4EC5, U+4ECD, U+4EE3-4EE4, U+4EEC, U+4EF6, U+4EFB, U+4EFD, U+4F2A, U+4F46, U+4F4D, U+4F4F, U+4F53, U+4F59, U+4F73, U+4F9D, U+4FBF, U+4FDD, U+503C, U+504F, U+505C, U+50CF, U+513F, U+5143, U+5148-5149, U+5165, U+5168, U+516C-516D, U+5171, U+518D, U+5199, U+51B3, U+51C0, U+51C6, U+51FD, U+5212, U+5219, U+521D, U+522B, U+529E, U+52A0, U+52A9, U+52BF, U+5305, U+5339, U+534A, U+5373, U+5385, U+538B, U+53BB, U+53C8, U+53CB-53CC, U+53D6-53D8, U+53E0, U+53EA, U+53F0, U+53F7, U+5408, U+540C-540D, U+5411, U+5448, U+544A, U+548C, U+552E, U+559C, U+566A, U+56DB, U+56E0, U+56FE, U+571F, U+5750, U+5757, U+575A, U+578B, U+57FA, U+5802, U+585E, U+5899, U+58C1, U+58F0, U+590F, U+5916, U+591A, U+591C, U+591F, U+5929-592A, U+5973, U+597D, U+5982, U+59FF, U+5A74, U+5A92, U+5B63, U+5B69, U+5B88, U+5B8C, U+5B98, U+5B9A, U+5BA2, U+5BA4, U+5BB6, U+5BC6, U+5BF8-5BF9, U+5BFC, U+5C01, U+5C04, U+5C3A, U+5C42, U+5C4B, U+5C4F, U+5C55, U+5CA9, U+5D4C, U+5DE2, U+5DE8, U+5DF1, U+5E03, U+5E55, U+5E72-5E73, U+5E84, U+5EA6-5EA7, U+5EAD, U+5EFA, U+5F20, U+5F2F, U+5F53, U+5F55, U+5F62, U+5F71, U+5F79, U+5F84, U+5F88, U+5FAA, U+5FAE, U+5FC5-5FC6, U+5FD7, U+6001, U+600E, U+6027, U+602A, U+610F, U+611F, U+6162, U+6216, U+622A, U+623F-6240, U+626E, U+6279, U+6296, U+62A2, U+62A4, U+62AC, U+62BD, U+62C5-62C6, U+62CD, U+62D2, U+62D6, U+62DB-62DC, U+62FF, U+6301, U+6309, U+632A, U+6362, U+636E, U+6389, U+6392, U+63A5, U+63A8, U+641C, U+642D, U+6446-6447, U+6491, U+64B0, U+652F, U+653B, U+653E, U+6545, U+6574, U+65AD, U+65BD, U+65C1, U+65CB, U+65E0, U+65E2, U+6620, U+665A, U+6670, U+66F4, U+66FF-6700, U+6709, U+670B, U+671D, U+6728, U+672B-672C, U+6750-6751, U+675F, U+6765, U+677F, U+6784, U+67E5, U+6811, U+6837, U+6839, U+6846, U+6848, U+6863, U+6869, U+68C0, U+6982, U+6B21-6B22, U+6B4C, U+6B62-6B63, U+6BB5, U+6BCF, U+6BD4-6BD5, U+6C42, U+6C99, U+6CA1, U+6CE2, U+6CE5, U+6CF0, U+6D1E, U+6D4B, U+6D77, U+6D82, U+6D88, U+6DE1, U+6DF1, U+6DF7, U+6E05, U+6E10, U+6E90, U+6EB6, U+6EE1, U+6EE4, U+6F0F, U+6F14, U+706B, U+7070, U+7075, U+7130, U+7136, U+7167, U+718A, U+7247-7248, U+7269, U+72EC, U+73A9, U+7531, U+7537, U+754C, U+7559, U+767D, U+76D6, U+76F4, U+76F8, U+7701, U+770B, U+77E9, U+77F3, U+7801, U+7834, U+786E, U+793A, U+7981, U+79BB, U+79CB, U+79CD, U+79EF, U+7A3F, U+7A74, U+7A76, U+7A7A, U+7A81, U+7ACB, U+7AD9, U+7ADF, U+7AEF, U+7B14, U+7B2C, U+7B49, U+7BA1, U+7C7B, U+7CBE, U+7D20, U+7D22, U+7D2B, U+7EA2, U+7EA6-7EA7, U+7EC6, U+7EC8, U+7ED3, U+7ED5, U+7ED9, U+7EED, U+7EF4, U+7EFF, U+7F16, U+7F18, U+7F29, U+7F51, U+7F6E, U+800C, U+8017, U+8033, U+804C, U+811A, U+82B1, U+8424, U+84DD, U+866B, U+8679, U+86D9, U+884C, U+8857, U+8868, U+88AB, U+89C2, U+89C4, U+89C6, U+89C9, U+89D2, U+89E3, U+8BA4, U+8BA9, U+8BB0, U+8BB2, U+8BBA, U+8BBF, U+8BC1, U+8BCD, U+8BD5, U+8BE5, U+8BFB, U+8C61, U+8D1D, U+8D28, U+8D62, U+8D70, U+8DB3, U+8DC3, U+8DD1, U+8DDD, U+8DDF, U+8EAB, U+8F6C, U+8F6F, U+8F7B, U+8F7D, U+8F83, U+8F91, U+8F93, U+8FA8, U+8FC7, U+8FD1, U+8FD8, U+8FDC, U+8FDE, U+8FEA, U+8FF0, U+8FF7, U+8FFD, U+9010, U+901A, U+9020, U+9053, U+9063, U+9075, U+90A3, U+90FD, U+914D, U+91C7, U+91CC, U+91CF, U+9488, U+9500, U+957F, U+95E8, U+95F4, U+9634-9636, U+9664, U+96BE, U+9700, U+9752, U+9759, U+9760, U+987B, U+9891, U+98DE, U+9971, U+9A6C, U+9A71, U+9A8C, U+9AA4, U+9AD8, U+9B42, U+9E1F, U+9E26, U+9EC4, U+9ED1}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/ui-jp-500.3c72cb35.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+65E5, U+672C, U+8A00, U+8A9E}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/ui-sc-500.8ce19281.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+4E2D, U+6587, U+8A00, U+8BED}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/ui-jp-600.7abc19e5.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+65E5, U+672C, U+8A00, U+8A9E}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/ui-sc-600.17072993.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+4E2D, U+6587, U+8A00, U+8BED}
@font-face{font-family:"LA Name JA";src:url("/assets/fonts/v1/name-ja-800.6f0cc43e.woff2") format("woff2");font-weight:800;font-style:normal;font-display:block;unicode-range:U+20, U+3000, U+4E09, U+5BFA, U+5EB5, U+706F, U+714C, U+7409}
@font-face{font-family:"LA Name JA";src:url("/assets/fonts/v1/ruby-ja-600.122fef57.woff2") format("woff2");font-weight:600;font-style:normal;font-display:block;unicode-range:U+20, U+3042, U+3044, U+304A, U+3058, U+3066, U+307F, U+308A, U+3093}
@font-face{font-family:"LA Name ZH";src:url("/assets/fonts/v1/name-zh-400.50476243.woff2") format("woff2");font-weight:400;font-style:normal;font-display:block;unicode-range:U+20, U+B7, U+5EB5, U+714C, U+7409}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-core-500.59e98534.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+3001-3002, U+300E-300F, U+3044, U+3057, U+3059, U+3066-3067, U+306E, U+3078, U+307E, U+308B, U+3092, U+30A2-30A4, U+30A6-30A9, U+30AB, U+30AD, U+30AF, U+30B2-30B3, U+30B6-30BA, U+30BD, U+30BF-30C1, U+30C3-30C4, U+30C6-30C8, U+30CB, U+30D7, U+30E0-30E1, U+30EA-30EB, U+30F3, U+30FB-30FC, U+4F5C, U+5236, U+58EB, U+5B66, U+5C02, U+623B, U+653B, U+767A, U+958B}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-core-more-500.f430b8c0.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+304D, U+306B, U+30AA, U+30B5, U+30C9-30CA, U+30D0, U+30D5-30D6, U+30DA, U+30DD, U+30E2-30E3, U+30E9, U+30EC-30ED, U+516C, U+5F0F, U+65B0, U+FF08-FF09, U+FF1A}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-core-600.6695fa18.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+20, U+3042, U+3044, U+3046, U+304A, U+304F, U+3054, U+3058, U+305D, U+3066, U+306E, U+307F, U+308A, U+3093, U+30A3-30A4, U+30A6-30A7, U+30A9, U+30B3, U+30B7-30BA, U+30BF-30C0, U+30D4-30D5, U+30D7, U+30E1-30E2, U+30E5, U+30EB-30ED, U+30FB-30FC, U+4E09, U+4ED6, U+4F5C, U+502B, U+54C1, U+5BFA, U+5E33, U+5EB5, U+5F90, U+6E08, U+706F, U+714C, U+7409, U+7CF8, U+FF08-FF09}
@font-face{font-family:"LA Sans JP";src:url("/assets/fonts/v1/sans-jp-core-more-600.d11996f0.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+3053, U+3057, U+305F, U+3064, U+3068, U+306B, U+30A2, U+30A8, U+30AA-30AB, U+30AD, U+30AF-30B0, U+30B2, U+30B5, U+30BD, U+30C1, U+30C3-30C4, U+30C6-30C8, U+30CE, U+30D0, U+30E0, U+30E3, U+30EA, U+30F3, U+4ECA, U+4F7F, U+5263, U+53D7, U+5584, U+5B50, U+5B57, U+5F53, U+5F8C, U+62C5, U+6539, U+6574, U+65B9, U+660E, U+6697, U+70B9, U+72B6, U+73FE, U+7528, U+76EE, U+7DDA, U+8272, U+8349, U+8AB2, U+8ABF, U+8CC7, U+8CDE, U+8F2A, U+90ED, U+91D1, U+9805, U+984C, U+FF1A}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-core-500.45ef5ec6.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+B7, U+3002, U+300A-300B, U+4E0E, U+4E3B, U+4F5C, U+5185, U+5230, U+5236, U+53D1, U+56DE, U+56E2, U+5728, U+5730, U+58EB, U+5927, U+5B66, U+5B9E, U+5BB9, U+5E08, U+5F00, U+620F, U+6211, U+6218, U+6280, U+6548, U+65F6, U+661F, U+672F, U+6E38, U+7279, U+7403, U+7684, U+7BB1, U+7EDD, U+7F8E, U+8981, U+8BA1, U+8BBE, U+8DF3, U+8FD4, U+90AE, U+961F}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-core-more-500.d74f68c3.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;unicode-range:U+4E0B, U+544A, U+54C1, U+5B58, U+5B98, U+5E78, U+5FD7, U+6253, U+65B0, U+65B9, U+6807, U+6B66, U+7247-7248, U+73A9, U+7AD9, U+7B7E, U+7F51, U+8005, U+843D, U+8BD5, U+8F7D, U+9668, U+96C6, U+9762, U+9875, U+9884, U+FF08-FF09, U+FF0C, U+FF1A}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-core-600.401008b6.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+B7, U+4E4B, U+4E8E, U+4ED6, U+4F26, U+4F5C, U+5173, U+5176, U+5236, U+5386, U+54C1, U+5668, U+5730, U+590D, U+5927, U+5DF2, U+5EB5, U+5F90, U+6218, U+661F, U+714C, U+7403, U+7409, U+7740, U+7B80, U+7EBF, U+7EDD, U+8272}
@font-face{font-family:"LA Sans SC";src:url("/assets/fonts/v1/sans-sc-core-more-600.8e6ac2cf.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap;unicode-range:U+20, U+4E00, U+4E0B, U+4E0E, U+4E1D, U+4E48, U+4E60, U+4E86, U+4EC0, U+4F7F, U+505A, U+5177, U+5217, U+5251, U+53C2, U+53EF, U+540E, U+56E2, U+58EB, U+5956, U+5B50, U+5B57-5B58, U+5B9E, U+5C0F, U+5C40, U+5DE5, U+5E78, U+5F69, U+60F3, U+620F, U+6211, U+63CF, U+6539, U+6548, U+6570, U+65B9, U+660E, U+6697, U+6B65-6B66, U+6CD5, U+6E38, U+7279, U+72B6, U+73B0, U+7406, U+751F, U+7528, U+7684, U+7CFB, U+7EB9, U+8005, U+81F4, U+8349, U+83C7, U+843D, U+8611, U+8C03, U+8C22, U+8D44, U+8D85, U+8FB9, U+8FDB, U+91D1, U+9650, U+9668, U+9879, U+989C, U+FF08-FF09, U+FF1A}

/* tokens.css: the design tokens of build spec v2 §2 (values from the Round 8 boards, R8-common.css and R8-motion.css).
   The v1 files in css/ stay as they are: /workroom still links them. */
:root {
  /* surfaces (§2.1) */
  --bg: #0a1016;
  --face: #0f1820;
  --key: #16212b;
  --tray: #0a1117;
  --topbar: #0b1319;
  --cbar: #0c141b;
  --well: #060a0e;

  /* ink */
  --ink-hot: #F4FAFD;
  --ink: #E7F1F7;
  --ink-dd: #DCE6EC;
  --ink-key: #C9D6DF;
  --ink-2: #C4D1DA;
  --ink-3: #A9BAC6;
  --ink-ruby: #9FB8C6;
  --ink-addr: #93A7B5;
  --ink-yr: #8FA3B1;
  --ink-tools: #8196A5;
  --ink-micro: #7D909E;
  --sep: #3E5363;

  /* cyan and pink */
  --cyan: #06D8E8;
  --cyan-l: #5FE6F0;
  --cyan-p: #C8FBFF;
  --pink: #F63A97;
  --pink-h: #FF4FA4;
  --pink-travel: #A3205F;
  --pink-ink: #16060F;
  --sig-base: #091a23; /* the live site's rendered base (its filter on the white path), near-black; R8 wrote #0b2a3a */

  /* ground */
  --dot: rgba(159, 178, 192, .085);
  --dot-boost: rgba(6, 216, 232, .55);

  /* type (§2.2): the subsets in assets/fonts/v1 are renamed (LA Display = Orbitron, LA Sans = IBM Plex Sans,
     LA Sans JP = IBM Plex Sans JP, LA Sans SC = Noto Sans SC, LA Name JA = M PLUS 1, LA Name ZH = ZCOOL QingKe HuangYou) */
  --f-display: "LA Display", sans-serif;
  --f-en: "LA Sans", system-ui, sans-serif;
  --f-ja: "LA Sans", "LA Sans JP", system-ui, sans-serif;
  --f-zh: "LA Sans", "LA Sans SC", system-ui, sans-serif;
  --f-cjk-ja: "LA Sans JP", system-ui, sans-serif;
  --f-cjk-zh: "LA Sans SC", system-ui, sans-serif;
  --f-name-ja: "LA Name JA", "LA Sans JP", sans-serif;
  --f-name-zh: "LA Name ZH", "LA Sans SC", sans-serif;

  /* focus (§5.2) */
  --focus: 2px solid #06D8E8;

  /* materials (§2.5) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .03 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23g)'/%3E%3C/svg%3E");
  /* Phase 4 materials pass (his "putty" note): the R8 stack plus a crisp bevel (brighter top edge, dark bottom edge), a
     darker outer hairline and a tighter contact shadow, so each object reads as a machined panel rather than a soft blob */
  --sh-face: inset 0 1px 0 rgba(255,255,255,.1), inset 0 0 0 1px rgba(231,241,247,.06), inset 0 -1px 0 rgba(0,0,0,.45), 0 0 0 1px rgba(0,0,0,.72), 0 1px 1px rgba(0,0,0,.5), 0 8px 14px -8px rgba(0,0,0,.6), 0 26px 44px -26px rgba(0,0,0,.9);
  --sh-face-hover: inset 0 1px 0 rgba(255,255,255,.12), inset 0 0 0 1px rgba(231,241,247,.075), inset 0 -1px 0 rgba(0,0,0,.45), 0 0 0 1px rgba(0,0,0,.72), 0 2px 3px rgba(0,0,0,.45), 0 14px 22px -10px rgba(0,0,0,.6), 0 40px 64px -26px rgba(0,0,0,.95);
  --sh-tray: inset 0 1px 3px rgba(0,0,0,.8), inset 0 0 0 1px rgba(0,0,0,.35), 0 1px 0 rgba(255,255,255,.05);
  --sh-key: inset 0 1px 0 rgba(255,255,255,.11), inset 0 0 0 1px rgba(231,241,247,.065), inset 0 -1px 0 rgba(0,0,0,.35), 0 3px 0 #05080b, 0 8px 14px -6px rgba(0,0,0,.7);
  --sh-key-hover: inset 0 1px 0 rgba(255,255,255,.11), inset 0 0 0 1px rgba(6,216,232,.4), inset 0 -1px 0 rgba(0,0,0,.35), 0 3px 0 #05080b, 0 8px 14px -6px rgba(0,0,0,.7);
  --sh-key-active: inset 0 1px 0 rgba(255,255,255,.05), inset 0 0 0 1px rgba(6,216,232,.4), 0 1px 0 #05080b, 0 3px 6px -3px rgba(0,0,0,.7);
  --sh-resume: inset 0 1px 0 rgba(255,214,234,.55), inset 0 -1px 0 rgba(120,10,60,.35), 0 3px 0 #A3205F, 0 10px 18px -8px rgba(0,0,0,.75);
  --sh-resume-active: inset 0 1px 0 rgba(255,214,234,.4), 0 1px 0 #A3205F, 0 4px 8px -4px rgba(0,0,0,.75);
  --sh-topbar: 0 1px 0 rgba(0,0,0,.6), 0 2px 0 rgba(255,255,255,.03), 0 14px 24px -16px rgba(0,0,0,.85);
  --sh-cbar: 0 -1px 0 rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05), 0 -18px 28px -14px rgba(0,0,0,.85);
  --ring-mask: linear-gradient(#000 0 0), linear-gradient(#000 0 0);
}

/* base.css: the page ground, type stacks, shared parts and the layout modes (build spec v2 §1.1, §1.2, §1.5, §1.6, §2). */
*, *::before, *::after { box-sizing: border-box; }
html { background: var(--bg); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; background: var(--bg); color: var(--ink);
  font-size: 16px; line-height: normal;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; }
a { color: var(--ink); text-decoration: none; }
button { font: inherit; color: inherit; }
img, video, svg { display: block; }
::selection { background: rgba(6, 216, 232, .25); }

/* type stacks by language (§2.2): switched with :lang(), set only where a lang attribute is, so a class that sets a face
   (the names, the section labels) is inherited by its children */
:where(html) { font-family: var(--f-en); }
:where([lang]:not(.twv):lang(en)) { font-family: var(--f-en); }
:where([lang]:not(.twv):lang(ja)) { font-family: var(--f-ja); line-break: strict; text-autospace: ideograph-alpha ideograph-numeric; }
:where([lang]:not(.twv):lang(zh)) { font-family: var(--f-zh); }
/* the typed layer of a string (.twv) carries the language it is typing, but never a stack of its own: it takes its
   string's face (the section labels' Orbitron, the phone name's CJK face), so a string keeps its font while it
   backspaces, and the face changes only at the swap, when <html lang> does (owner review 2026-09-26, items 7 and 8) */

/* visually hidden, still read */
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
svg.sprite { display: none; }

/* skip link: first focusable, shown on focus only */
.skip {
  position: fixed; left: 16px; top: 12px; z-index: 20; padding: 10px 14px; border-radius: 10px;
  background: var(--key); color: var(--ink-hot); font-size: 14px; line-height: 20px; font-weight: 500;
  box-shadow: var(--sh-key); transform: translateY(-200%);
}
.skip:focus { transform: none; outline: var(--focus); outline-offset: 4px; }
main:focus { outline: none; }

/* default focus ring for anything without its own (§5.2) */
:focus-visible { outline: var(--focus); outline-offset: 2px; }

/* ground (§1.2, §3.6.2): the dot grid and the boost layer, fixed under everything. light.js lights the boost (Phase 4) */
.dots, .boost { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
.dots { background-image: radial-gradient(var(--dot) 1px, transparent 1.4px); background-size: 20px 20px; }
.boost {
  --mx: -999px; --my: -999px;
  background-image: radial-gradient(var(--dot-boost) 1px, transparent 0); background-size: 20px 20px;
  -webkit-mask-image: radial-gradient(circle 200px at var(--mx) var(--my), #000 0, rgba(0,0,0,.8) 12px, transparent 200px);
  mask-image: radial-gradient(circle 200px at var(--mx) var(--my), #000 0, rgba(0,0,0,.8) 12px, transparent 200px);
  mix-blend-mode: screen; opacity: 0;
}

/* typed strings (§3.5): the final text (.vh), the ghost that shows at rest (.twg) and the typed layer (.twv, empty
   until a sequence runs). A rich string (.tw.r) has no separate final layer: its ghost is the real, focusable copy */
.tw { position: relative; display: block; }
.tw.i { display: inline-block; vertical-align: top; }
.twv { display: none; position: absolute; left: 0; top: 0; width: 100%; pointer-events: none; }
/* (a click while it types reaches what sits under the copy: a rich string's real links, a tile's link) */
.tw.i .twv { white-space: nowrap; }
.twr .twv { display: block; }
.twr .twg { visibility: hidden; }
.twr .tw.r > .twg { visibility: visible; opacity: 0; }
/* a string far from the viewport does not type (js/v2/typed.js near()): its ghost stays, and changes at the swap */
.twr .tw.twq > .twg { visibility: visible; opacity: 1; }
.twc { display: none; }
.twc.on { display: inline-block; width: .46em; height: 1.02em; margin-left: .06em; vertical-align: -.16em; background: var(--cyan); opacity: .9; }
/* the typed layer is a copy of the ghost, formatting and all (js/v2/typed.js): the characters not typed yet keep their
   place, hidden (.twm), so nothing reflows while a string types and nothing moves at the handoff. Its cursor sits out
   of flow at the insertion point (no width, no break opportunity); its own line puts the drawn bar on the text's
   baseline exactly where the in-flow cursor sat */
.twm { visibility: hidden; }
.twv.fix { white-space: nowrap; }
.twc.on.z { display: inline; position: absolute; width: auto; height: auto; margin: 0; vertical-align: baseline; background: none; opacity: 1; white-space: nowrap; visibility: visible; font-style: normal; }
.twc.on.z::before { content: ""; display: inline-block; width: .46em; height: 1.02em; margin-left: .06em; vertical-align: -.16em; background: var(--cyan); opacity: .9; }
.tw.r a { color: var(--cyan-l); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: rgba(95, 230, 240, .45); }
.tw.r a:hover { color: var(--cyan); text-decoration-color: currentColor; }
.tw.r a:focus-visible { outline: var(--focus); outline-offset: 2px; border-radius: 2px; }

/* runs of parts (§2.6): a line only breaks between parts; a separator that would start a line is clipped */
.parts { display: flex; flex-wrap: wrap; column-gap: 15px; overflow: hidden; overflow: clip; }
.parts > span { position: relative; white-space: nowrap; }
.parts > span + span::before { content: "·"; position: absolute; right: calc(100% + 5px); top: 0; opacity: .55; }
.parts.sl { column-gap: 17px; }
.parts.sl > span + span::before { content: "/"; opacity: 1; color: var(--sep); }

/* small caps-like labels and the engraved rule */
.micro { font-size: 12px; line-height: 16px; letter-spacing: .08em; color: var(--ink-micro); }
.groove { height: 0; border-top: 1px solid rgba(0,0,0,.6); border-bottom: 1px solid rgba(255,255,255,.05); }
.head { display: flex; align-items: center; gap: 12px; }
.head .lb { font-family: var(--f-display); font-size: 12px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; color: var(--cyan); }
.head .groove { flex: 1; }
:lang(ja) .head .lb { font-family: var(--f-cjk-ja); font-size: 14px; letter-spacing: .14em; text-transform: none; font-feature-settings: "palt"; }
:lang(zh) .head .lb { font-family: var(--f-cjk-zh); font-size: 14px; letter-spacing: .14em; text-transform: none; }

/* the material every object is made of (§2.5). --lx/--ly/--li are written by the pointer light (Phase 4) on every
   pointer move. light.js registers them as not inherited where the engine passes them on to the rim correctly, so a
   write restyles the face and its rim only, not every element inside it (the 4x CPU trace, Phase 7); the rim takes
   them from its face explicitly. Unregistered, they simply inherit, as before */
.face {
  position: relative; --lx: -999px; --ly: -999px; --li: 0;
  background-color: var(--face);
  background-image: radial-gradient(circle 360px at var(--lx) var(--ly), rgba(159,246,252,calc(.055 * var(--li) * var(--lg, 1))), rgba(159,246,252,0) 70%), var(--grain);
  box-shadow: var(--sh-face);
}
/* the content panels (the work column's panels and a project's frame) take about two thirds of the pointer's light: at
   full strength it read a bit bright on them (owner review 2026-09-26, item 5). The identity card and the signature
   keep theirs. --lg is an ordinary inherited property, so the rim below reads it from its face */
.panel, .proj { --lg: .67; }
/* the rim: a 1 px ring over everything in the object, the screens included. The pointer's light (R8, scaled by --li
   instead of the layer's opacity) over a fixed specular edge: brightest along the top, where the room's light falls,
   and fading down the sides, so every edge is crisp at rest (Phase 4 materials pass) */
.face::before {
  content: ""; position: absolute; inset: 0; z-index: 4; border-radius: inherit; padding: 1px; pointer-events: none;
  --lx: inherit; --ly: inherit; --li: inherit;
  background:
    radial-gradient(circle 230px at var(--lx) var(--ly), rgba(214,252,255,calc(.95 * var(--li) * var(--lg, 1))), rgba(6,216,232,calc(.4 * var(--li) * var(--lg, 1))) 38%, rgba(6,216,232,0) 72%),
    linear-gradient(180deg, rgba(226,246,255,.2), rgba(226,246,255,.07) 90px, rgba(226,246,255,.035) 60%, rgba(226,246,255,.02));
  -webkit-mask-image: var(--ring-mask); -webkit-mask-clip: content-box, border-box; -webkit-mask-composite: xor;
  mask-image: var(--ring-mask); mask-clip: content-box, border-box; mask-composite: exclude;
}

/* icons: 24 x 24 outlines from the sprite */
.ico { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* ======================================================================================
   LAYOUT MODES (§1.1): one DOM; desktop >= 1200, between 481-1199, phone <= 480
   ====================================================================================== */
.page { position: relative; z-index: 1; }
.topbar, .cbar { display: none; }

/* desktop (§1.3.1, Q4 default): grid 424 + 720, gap 40, padding 40 top and 112 left; the right 144 px stay clear
   for the signature. The bottom padding keeps the board's ground under the footer (the frame is 1780 tall in EN) */
/* Centred (owner review 2026-09-26, item 1): the card + work column (424 + 40 + 720 = 1184 px) sits centred in the
   window at wide widths. At 1440 it keeps the board's 112 px left edge (16 px left of centre, the signature's side);
   that 16 px offset fades out by 1600 px, and from there the composition is exactly centred however wide the window.
   Below 1440 the board's clamp rules as before. --page-l is left as text: its 50 % and 100 % resolve where it is used,
   against the page's containing block (padding) or the viewport (the fixed language dock), the same width. */
@media (min-width: 1200px) {
  :root { --page-l: max(clamp(48px, 7.78vw, 112px), calc(50% - 592px - max(0px, 16px - (100% - 1440px) / 10))); }
  .page {
    display: grid; grid-template-columns: 424px minmax(0, 720px); grid-template-rows: auto 1fr; column-gap: 40px;
    justify-content: start; padding: 40px 144px 125px var(--page-l);
  }
  .id-col { grid-column: 1; grid-row: 1 / span 2; position: relative; }
  .id-stick { position: sticky; top: 40px; z-index: 6; }
  main { grid-column: 2; grid-row: 1; min-width: 0; }
  .foot { grid-column: 2; grid-row: 2; margin-top: 56px; }
}

/* phone and between (§1.4, §1.5): sticky top bar, fixed contact bar, the card in flow at the top; a centred column
   of at most 720 px with 16 px minimum side padding */
@media (max-width: 1199px) {
  html { scroll-padding-top: 72px; scroll-padding-bottom: 100px; }
  .page { max-width: 752px; margin: 0 auto; padding: 16px 16px 100px 16px; }
  .foot { margin-top: 40px; }
}

/* footer (§1.3.8) */
.foot a { color: var(--ink-yr); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: rgba(143, 163, 177, .35); }
.foot a:hover { color: var(--cyan); text-decoration-color: currentColor; }
.foot .sep { padding: 0 8px; color: var(--sep); }

/* forced colours (§2.1, §5.9) */
@media (forced-colors: active) {
  .boost { display: none; }
  :focus-visible { outline: 2px solid Highlight; }
}

/* card.css: the identity card, his name, the contact tray and keys, the signature, the phone bars
   (build spec v2 §1.3.2, §1.3.3, §1.3.9, §1.4, §1.5, §1.6, §1.8, §2.5). */

/* ---------------------------------------------------------------- the card */
.idc {
  --ph: 480px; --kx: 47.3%; --ky: 169px;
  display: flex; flex-direction: column; border-radius: 20px;
}
/* the helmet ring is the card's key light: rim, bloom and spill all come from --kx/--ky. The breath is in motion.css */
.idc::after {
  content: ""; position: absolute; inset: 0; z-index: 4; border-radius: inherit; padding: 1px; pointer-events: none;
  background: radial-gradient(circle 440px at var(--kx) var(--ky), rgba(190,250,255,.9), rgba(6,216,232,.42) 36%, rgba(6,216,232,0) 74%);
  -webkit-mask-image: var(--ring-mask); -webkit-mask-clip: content-box, border-box; -webkit-mask-composite: xor;
  mask-image: var(--ring-mask); mask-clip: content-box, border-box; mask-composite: exclude;
  opacity: .5;
}
.por-wrap { position: relative; flex: none; }
.por { position: relative; height: var(--ph); overflow: hidden; border-radius: 20px 20px 0 0; background: var(--well); }
.por img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
/* The portrait's foot (owner review 2026-09-26, item 3). It used to be darkened by a four-stop gradient to the card's
   flat colour (.por-fade, §2.5), which banded at the stops and ended in a seam: the card below it has the grain, the
   pointer's light and the spill, the fade's #0f1820 had none of them. Now the portrait itself fades out through a mask
   along the same curve (0.5 at 62 %, 0.9 at 84 %, as the fade had it, but eased smooth at both ends,
   (1 - u^1.3)^2.2), so what shows through its foot is the card's own surface and there is no edge to see */
.por {
  -webkit-mask-image: linear-gradient(180deg, #000 40%, rgba(0,0,0,.915) 45%, rgba(0,0,0,.798) 50%, rgba(0,0,0,.673) 55%, rgba(0,0,0,.547) 60%, rgba(0,0,0,.427) 65%, rgba(0,0,0,.318) 70%, rgba(0,0,0,.221) 75%, rgba(0,0,0,.14) 80%, rgba(0,0,0,.077) 85%, rgba(0,0,0,.033) 90%, rgba(0,0,0,.007) 95%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 40%, rgba(0,0,0,.915) 45%, rgba(0,0,0,.798) 50%, rgba(0,0,0,.673) 55%, rgba(0,0,0,.547) 60%, rgba(0,0,0,.427) 65%, rgba(0,0,0,.318) 70%, rgba(0,0,0,.221) 75%, rgba(0,0,0,.14) 80%, rgba(0,0,0,.077) 85%, rgba(0,0,0,.033) 90%, rgba(0,0,0,.007) 95%, transparent 100%);
}
.por::after { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; box-shadow: inset 0 1px 0 rgba(255,255,255,.09); }
.por-bloom {
  position: absolute; left: var(--kx); top: var(--ky); width: 180px; height: 180px; margin: -90px 0 0 -90px; border-radius: 50%;
  pointer-events: none; mix-blend-mode: screen; opacity: .55;
  background: radial-gradient(circle, rgba(6,216,232,.3) 0, rgba(6,216,232,.1) 30%, rgba(6,216,232,0) 68%);
}
.spill { --sp: 300px; position: absolute; left: 0; right: 0; top: var(--ph); height: var(--sp); pointer-events: none; background: radial-gradient(ellipse 62% var(--sp) at var(--kx) 0, rgba(6,216,232,.06), rgba(6,216,232,0) 70%); }
/* the spill's light also rises a little into the portrait's faded foot, so it has no top edge at the seam: the same
   ellipse mirrored upward, tapering out over 120 px */
.spill::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 120px;
  background: radial-gradient(ellipse 62% var(--sp) at var(--kx) 100%, rgba(6,216,232,.06), rgba(6,216,232,0) 70%);
  -webkit-mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,.109) 25%, rgba(0,0,0,.33) 50%, rgba(0,0,0,.631) 75%, #000);
  mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,.109) 25%, rgba(0,0,0,.33) 50%, rgba(0,0,0,.631) 75%, #000);
}

/* ---------------------------------------------------------------- his name (§1.3.2, §3.2) */
.nm {
  position: absolute; left: 28px; margin: 0; z-index: 1; color: var(--ink-hot); white-space: nowrap; font-weight: 400;
  text-shadow: 0 2px 24px rgba(4,8,12,.55);
}
.nm .nl { display: block; }
.nm-en { bottom: -30px; font-family: var(--f-display); font-weight: 700; font-size: 68px; line-height: 63px; letter-spacing: 0; }
.nm-t { display: block; font-kerning: none; font-feature-settings: "palt" 0; }
.bl { display: inline-block; width: 0; height: 0; }
.nm-ja { --fs: 64px; --bls: calc(var(--fs) * .03); bottom: -30px; font-family: var(--f-name-ja); font-weight: 800; font-size: var(--fs); line-height: 85px; letter-spacing: var(--bls); }
.nm-zh { --fs: 84px; --bls: calc(var(--fs) * .05); bottom: -24px; font-family: var(--f-name-zh); font-weight: 400; font-size: var(--fs); line-height: 84px; letter-spacing: var(--bls); }
/* furigana (§3.2): generated kana, so a copy of the name gives the name alone. --bls is the name's letter-spacing in px.
   The kana's line box is M PLUS 1's own (the furigana face declares the space, as the prototype's single face did), so
   the two lines sit 85 px apart and the kana sit as tight to the name as in preview_v4.html */
.nm-ja rt {
  font-family: "LA Name JA", sans-serif; font-weight: 600; font-size: .215em; color: var(--ink-ruby); text-shadow: none;
  position: relative; top: .1em; left: calc(var(--bls) * -.5); letter-spacing: .08em; padding-left: .08em;
  -webkit-user-select: none; user-select: none;
}
.nm-ja rt.wide { letter-spacing: .42em; padding-left: .42em; }
.nm .k { display: inline-block; }
.nm .k::before { content: attr(data-k); }
.nm .sr::before { content: attr(data-sr); }
.nm .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---------------------------------------------------------------- identity text */
.ident { position: relative; }
.ident-t { padding: 46px 28px 0 28px; }
.role { font-size: 21px; line-height: 28px; font-weight: 500; color: var(--ink-hot); }
.studio { margin-top: 6px; font-size: 15px; line-height: 22px; color: var(--ink-2); }
.studio > span { display: block; }
.loadout { margin-top: 14px; font-size: 13px; line-height: 20px; letter-spacing: .02em; color: var(--ink-tools); }
:lang(ja) .role, :lang(zh) .role { font-feature-settings: "palt"; letter-spacing: .03em; }

/* ---------------------------------------------------------------- the contact line (SP08 "Footer line")
   His pick of the share-panel round (2026-09-26 18:52: "ooooh I REALLY love Footer line"), replacing the tray of keys
   and the phone's key bar. One even line of text links, Resume · Email · LinkedIn · GitHub, Resume in pink with its
   download glyph, thin dots between, an underline that slides in under the word on hover or focus. Email swaps the
   line for the mail row (address · Copy · Back; js/v2/contact.js). The same markup is the card's foot on desktop
   (.tray) and the phone's bottom bar (.cbar). The address link stays empty until intent (Q6, §1.8). */
.fl { position: relative; }
.fl-row { display: flex; align-items: center; justify-content: center; gap: 18px; height: 100%; }
.fl-row[hidden] { display: none; }
.fl .dot { width: 3px; height: 3px; border-radius: 50%; background: #4A5F6E; flex: none; }
.fk {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px; flex: none; height: 44px;
  margin: 0; padding: 0; border: 0; border-radius: 4px; background: none; cursor: pointer;
  font: inherit; font-size: 15px; font-weight: 500; letter-spacing: .01em; line-height: 20px; white-space: nowrap;
  color: var(--ink-2); transition: color .2s;
}
.fk .fk-i { width: 16px; height: 16px; stroke-width: 1.7; }
.fk-t { position: relative; display: inline-block; }
.fk-t::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 1.5px; background: currentColor;
  transform: scaleX(0); transform-origin: 0 50%; transition: transform .22s ease-out;
}
.fk:hover, .fk:focus-visible { color: var(--ink-hot); }
.fk:hover .fk-t::after, .fk:focus-visible .fk-t::after { transform: scaleX(1); }
.fk:focus-visible { outline: var(--focus); outline-offset: 2px; }
.fk.resume { color: var(--pink); font-weight: 600; }
.fk.resume:hover, .fk.resume:focus-visible { color: var(--pink-h); }
.fk.cpy { color: var(--cyan); font-weight: 600; }
.fk.cpy:hover, .fk.cpy:focus-visible { color: var(--cyan-l); }
.fk.addr { flex: 0 1 auto; min-width: 0; color: var(--ink); }
.fk.addr .fk-t, .fk.addr { overflow: hidden; text-overflow: ellipsis; }
.cpy .c-b, .cpy .i-b { display: none; }
.cpy.done { color: var(--cyan-l); }
.cpy.done .c-a, .cpy.done .i-a { display: none; }
.cpy.done .c-b { display: inline; }
.cpy.done .i-b { display: block; }
/* the swap: the row that comes in fades up from a 2 px drop (only after the first swap, never at load) */
.fl.sw .fl-row:not([hidden]) { animation: flIn .18s cubic-bezier(.2,.7,.3,1); }
@keyframes flIn { from { opacity: 0; transform: translateY(2px); } }
@media (prefers-reduced-motion: reduce) {
  .fk, .fk-t::after { transition: none; }
  .fl.sw .fl-row:not([hidden]) { animation: none; }
}

/* the card's foot (desktop): the line sits 22 px under the tools, 60 tall, 16 in from the card's sides and 10 from its
   bottom, with a hairline groove along its top */
.tray {
  flex: none; height: 60px; margin: 22px 16px 10px 16px;
  border-top: 1px solid rgba(0,0,0,.6); box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
}

/* ---------------------------------------------------------------- the signature (§1.3.9, §3.6.1): dark at rest */
.sig { position: relative; flex: none; pointer-events: none; --sx: -200%; --sy: -200%; }
.sig svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sig-wrap {
  position: absolute; inset: 0;
  -webkit-mask-image: radial-gradient(circle at var(--sx) var(--sy), #000 0%, #000 25%, transparent 60%);
  mask-image: radial-gradient(circle at var(--sx) var(--sy), #000 0%, #000 25%, transparent 60%);
}
.sig-lit {
  -webkit-mask-image: url("/assets/images/anmiteiji_outline.svg"); -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: -1px -1px; -webkit-mask-size: calc(100% + 2px) calc(100% + 2px);
  mask-image: url("/assets/images/anmiteiji_outline.svg"); mask-repeat: no-repeat;
  mask-position: -1px -1px; mask-size: calc(100% + 2px) calc(100% + 2px);
  filter: blur(3px) hue-rotate(165deg);
}
/* the WebGL light (js/v2/sig-gl.js) draws on its own canvas over the base. The SVG lit layer is the no-WebGL fallback:
   with JS it is drawn (and its outline mask fetched) only once light.js has chosen it (.svg); without JS nothing lights
   the signature, so it is never drawn either */
.sig:not(.svg) .sig-wrap { display: none; }
.sigbg { position: fixed; right: 20px; top: 24px; z-index: 0; pointer-events: none; }
.sigbg .sig { width: 116px; height: 438px; }
.ident > .sig { display: none; }

/* ---------------------------------------------------------------- desktop: the sticky card (§1.3.2, §1.6) */
@media (min-width: 1200px) {
  /* short windows: the portrait shrinks first so the tray stays on screen; the ring's light follows the crop */
  /* the card is as tall as its content (portrait + 158 of text + 93 of contact line = 731 at full size); with the one-line
     contact foot (SP08) it no longer reserves the old tray's 174 px */
  .idc { --ph: clamp(280px, calc(100svh - 331px), 480px); --ky: calc(169px - (480px - var(--ph)) * .1); }
  .idc .spill { height: auto; bottom: 0; }
  .por img { object-position: 50% 10%; }
}

/* ---------------------------------------------------------------- phone and between (§1.4, §1.5) */
@media (max-width: 1199px) {
  .sigbg { display: none; }
  .tray { display: none; }
  .idc { --ph: 400px; --ky: 141px; border-radius: 18px; }
  .por { border-radius: 18px 18px 0 0; }
  .spill { --sp: 220px; }
  .nm { left: 20px; }
  /* 58/54 from 368 px up; below that the name steps down so "Armitage" stays inside the card (reflow at 320) */
  .nm-en { bottom: -24px; font-size: min(58px, calc((100vw - 52px) * .197)); line-height: .931em; }
  .nm-ja { --fs: 52px; bottom: -24px; line-height: 69px; }
  .nm-zh { --fs: 68px; bottom: -20px; line-height: 68px; }
  .ident { display: grid; grid-template-columns: minmax(0, 1fr) 32px; column-gap: 14px; padding: 0 20px 22px 20px; }
  .ident-t { padding: 40px 0 0 0; }
  .ident > .sig { display: block; width: 32px; height: 121px; margin-top: 14px; }
  .role { font-size: 19px; line-height: 26px; }
  :lang(ja) .role { font-size: 17px; }
  .studio { margin-top: 4px; font-size: 13.5px; line-height: 21px; }
  .loadout { margin-top: 12px; font-size: 12.5px; line-height: 20px; }

  /* top bar (§1.4): sticky, his headshot, name and role on the left, the language control at the right edge. 60 px, 4 up
     on the board's 56 (his "the tiniest bit bigger", 2026-09-26 16:14), with the small round headshot he asked for
     (16:09): the card's own avatar, cropped to the helmet */
  .topbar {
    position: sticky; top: 0; z-index: 9; display: flex; align-items: center; gap: 12px; height: 60px; padding: 0 16px;
    background-color: var(--topbar); box-shadow: var(--sh-topbar);
  }
  .tb-av {
    position: relative; flex: none; width: 36px; height: 36px; border-radius: 50%; overflow: hidden; background: var(--well);
    box-shadow: 0 0 0 1px rgba(231,241,247,.12);
  }
  /* its own 108 px square on the helmet (scripts/avatar.py --headshot, about 2 KB), so a phone project page, which
     has no card, does not fetch the 848 px portrait for a 36 px circle; a background, not an <img>, so it never takes
     part in the portrait's LCP */
  .tb-av {
    background: var(--well) url("/assets/avatar/v1/headshot-108.jpg") 50% 50% / cover no-repeat;
    background-image: image-set(url("/assets/avatar/v1/headshot-108.avif") type("image/avif"), url("/assets/avatar/v1/headshot-108.webp") type("image/webp"), url("/assets/avatar/v1/headshot-108.jpg") type("image/jpeg"));
  }
  .tb-id { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
  .tb-nm { font-size: 15px; line-height: 18px; font-weight: 600; color: var(--ink-hot); white-space: nowrap; }
  html:lang(en) .tb-nm { font-family: var(--f-display); font-weight: 700; letter-spacing: .03em; }
  /* JA: the one-line name 琉煌・庵三灯寺 (strings.js JA_ONE_LINE_SEP): "palt" sets the ・ at its proportional width
     instead of a full em, so it reads as a dot between the names, not a gap (owner review 2026-09-26, item 10) */
  html:lang(ja) .tb-nm { font-family: var(--f-cjk-ja); font-size: 16px; letter-spacing: .06em; font-feature-settings: "palt"; }
  /* ZH: 琉煌·庵's U+00B7 from Plex (LA Sans), the narrow dot the name was typed with, not Noto Sans SC's wide one; the
     CJK characters still come from LA Sans SC (owner review 2026-09-26, item 9) */
  html:lang(zh) .tb-nm { font-family: "LA Sans", var(--f-cjk-zh); font-size: 16px; letter-spacing: .06em; }
  .tb-role { font-size: 12px; line-height: 16px; color: var(--ink-yr); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tb-role .tw, .tb-role .twg, .tb-role .twv { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .tb-role .twg { display: block; }

  /* the contact bar (§1.4, SP08): the same line as the card's foot, as a slim text bar docked to the bottom, 52 px
     (2 + 44 + 6) over the safe area, smaller than the old 76 (his "a tiny bit oversized") */
  .cbar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 9; display: block; height: calc(52px + env(safe-area-inset-bottom));
    padding: 2px 12px calc(6px + env(safe-area-inset-bottom));
    background-color: var(--cbar); box-shadow: var(--sh-cbar);
  }
  .cbar .fl-row { gap: min(14px, 3.6vw); }
  .cbar .fk { min-width: 44px; font-size: 14px; }
  .page { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
  html { scroll-padding-top: 76px; scroll-padding-bottom: 72px; }

  /* a project page (his 2026-09-26 16:09 note): the top bar and the contact bar already carry his name and contact, so
     the identity card is not repeated above the project, and "Back to portfolio" gets its own air under the top bar.
     The home page keeps the big card (his call, 17:38). Matches the prerendered project page and, once the router has
     wrapped the views, a shown project view (a view leaving in the morph is aria-hidden, so it does not count) */
  .page:has(> #main > .proj, > #main > .vw[data-view^="project"]:not([hidden]):not([aria-hidden="true"])) { padding-top: 24px; }
  .page:has(> #main > .proj, > #main > .vw[data-view^="project"]:not([hidden]):not([aria-hidden="true"])) > .id-col { display: none; }
  .page:has(> #main > .proj, > #main > .vw[data-view^="project"]:not([hidden]):not([aria-hidden="true"])) .back { height: 44px; margin-bottom: 18px; }
}

/* the portrait crop keeps the whole helmet in the frame when the card is wider than the photo (481-1199 and the
   widest phones): the photo sits 5 % from its top, and the ring's light follows it.
   Card width = min(720, 100vw - 32); photo height at that width = width x 480 / 424; ring at 35.4 % of the photo */
@media (min-width: 400px) and (max-width: 1199px) {
  .idc { --cw: min(720px, calc(100vw - 32px)); --hs: calc(var(--cw) * 1.1321); --ky: calc(var(--hs) * .354 - (var(--hs) - var(--ph)) * .05); }
  .por img { object-position: 50% 5%; }
}
@media (min-width: 481px) and (max-width: 1199px) {
  .idc { --ph: min(480px, 62.5vw); }
}

@media (forced-colors: active) {
  .sig-wrap, .sig-gl { display: none; }
  .sig-base { forced-color-adjust: auto; }
  .fk-t::after { background: LinkText; }
}
/* Behind his name, above the seam only: a soft shade that keeps the name's ground as dark as the old fade left it
   (the card's grain now shows through the portrait's foot, about 4 levels lighter), so the write-in reads the same
   against it (check31's ink threshold is measured against that ground: without it, one half-drawn row of 庵's last
   stroke read as a hole). It is 0 at its bottom edge, the seam, and fades smoothly everywhere, so it has no edge */
.por-wrap::after {
  content: ""; position: absolute; left: 0; right: 0; top: calc(var(--ph) - 170px); height: 170px; pointer-events: none;
  background: radial-gradient(ellipse 80% 50% at 34% 50%, rgba(5,9,13,.42), rgba(5,9,13,.33) 30%, rgba(5,9,13,.16) 60%, rgba(5,9,13,.05) 85%, rgba(5,9,13,0));
}

/* panels.css: the work column at rest: the hero panel, the four tiles, About and Elsewhere
   (build spec v2 §1.3.4 to §1.3.7, §1.4, §1.5, §2.2 CJK rules, §5.3).
   The column is the board's 720 px desktop column whenever it has the room (>= 672 px wide viewports, a column of
   640 px or more); below that it takes the phone board's values. Hover lift, glint and preview play are Phase 4. */

.work { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; list-style: none; }
.work > li { display: flex; min-width: 0; }
.work > .w-hero { grid-column: 1 / -1; }
.panel { flex: 1; min-width: 0; display: flex; flex-direction: column; color: var(--ink); border-radius: 16px; }
.panel.hero { border-radius: 18px; }

/* the whole panel is the title link's hit area (§5.3); the focus ring is drawn around the panel */
.panel h3 a { color: inherit; }
.panel h3 a::after { content: ""; position: absolute; inset: 0; z-index: 3; border-radius: inherit; }
.panel h3 a:focus-visible { outline: none; }
.panel:has(h3 a:focus-visible) { outline: var(--focus); outline-offset: 4px; }
.panel:hover, .panel:has(h3 a:focus-visible) { box-shadow: var(--sh-face-hover); }

.glint {
  position: absolute; inset: 0; z-index: 5; border-radius: inherit; padding: 1px; pointer-events: none; opacity: 0;
  background-image: linear-gradient(100deg, rgba(255,255,255,0) 42%, rgba(234,254,255,.95) 50%, rgba(255,255,255,0) 58%);
  background-size: 300% 100%; background-position: 100% 0; background-repeat: no-repeat;
  -webkit-mask-image: var(--ring-mask); -webkit-mask-clip: content-box, border-box; -webkit-mask-composite: xor;
  mask-image: var(--ring-mask); mask-clip: content-box, border-box; mask-composite: exclude;
}

/* screens: the picture runs to the panel's edges (no inset, no caption) */
.scr { position: relative; flex: none; overflow: hidden; background: var(--well); border-radius: 16px 16px 0 0; aspect-ratio: 16 / 9; }
.hero .scr { border-radius: 18px 18px 0 0; aspect-ratio: 2.4; }
/* the rounded corners hold for a playing loop (owner review 2026-09-26: it "pokes out of the rounded edges";
   design-lab/r10/morph NOTES.md rounds 3 and 4, confirmed in his Chrome). overflow + border-radius alone does not
   reliably clip a composited <video> (a GPU video layer, or the hover lift's transform, can escape it). So the well
   isolates and clips itself with clip-path, its bottom edge 2 px open for its 1 px lower highlight; the picture takes
   the same radius; and the video carries a solid mask, which changes no pixel but keeps Chrome from handing it to the
   OS as an overlay or its own delegated layer, so its radius and the well's clip always apply (native controls sit
   inside the <video> and are clipped with it). The morph animates this clip with the well's counter-scaled radius. */
.scr { isolation: isolate; clip-path: inset(0 0 -2px 0 round 16px 16px 0 0); }
.hero .scr, .proj > .scr { clip-path: inset(0 0 -2px 0 round 18px 18px 0 0); }
.scr picture, .scr video, .scr img { border-radius: inherit; }
.scr video { -webkit-mask-image: linear-gradient(#000, #000); mask-image: linear-gradient(#000, #000); }
/* the clip makes the well a stacking context, which would put the hero's pause button under the panel's link (z 3):
   the hero's well sits above the link but lets every pointer through to it, except on the button */
.hero .scr { z-index: 4; pointer-events: none; }
.hero .scr .vpause { pointer-events: auto; }
.scr::before { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; pointer-events: none; box-shadow: inset 0 1px 0 rgba(255,255,255,.08); }
.scr::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: 1px; background: rgba(0,0,0,.75); box-shadow: 0 1px 0 rgba(255,255,255,.05); }
.scr video, .scr img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.scr video { filter: brightness(.8) saturate(.9); }
.hero .scr video { filter: none; }
.still { z-index: 1; filter: brightness(.86) saturate(.92); }
.pix, .pix video, .pix img { image-rendering: pixelated; }

/* text */
.panel .txt { flex: 1; display: flex; flex-direction: column; padding: 16px 20px 18px 20px; }
.hero .txt { padding: 20px 24px 22px 24px; }
.trow { display: flex; align-items: baseline; gap: 12px; }
.hero .trow { gap: 16px; }
.panel h3 { flex: 1; min-width: 0; font-size: 17px; line-height: 24px; font-weight: 600; text-wrap: balance; }
.hero h3 { font-size: 28px; line-height: 34px; }
.yr { font-size: 12px; letter-spacing: .1em; color: var(--ink-yr); font-variant-numeric: tabular-nums; white-space: nowrap; }
.meta { color: var(--cyan-l); }
.panel .meta { margin-top: 5px; font-size: 13.5px; line-height: 20px; }
.hero .meta { margin-top: 6px; font-size: 15px; line-height: 22px; }
.brow { display: flex; align-items: flex-end; gap: 16px; margin-top: auto; padding-top: 6px; }
.hero .brow { gap: 24px; margin-top: 6px; padding-top: 0; }
.desc { flex: 1; min-width: 0; font-size: 14px; line-height: 21px; color: var(--ink-2); text-wrap: pretty; }
.hero .desc { max-width: 620px; font-size: 15px; line-height: 22px; }
.op { display: inline-grid; align-items: center; justify-items: end; flex: none; height: 24px; }
.op-arr { width: 18px; height: 18px; fill: none; stroke: var(--ink-yr); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.hero .op-arr { stroke: var(--ink-key); }
.panel:hover .op-arr, .panel:has(h3 a:focus-visible) .op-arr { stroke: var(--cyan); }

/* CJK set as carefully as the Latin (§2.2) */
:lang(ja) .panel h3, :lang(ja) .meta, :lang(ja) .gw-d, :lang(zh) .panel h3, :lang(zh) .meta { font-feature-settings: "palt"; }
:lang(ja) .panel h3 { letter-spacing: .02em; word-break: keep-all; overflow-wrap: anywhere; }
:lang(zh) .panel h3 { letter-spacing: .03em; }
:lang(ja) .panel p:not(.meta), :lang(zh) .panel p:not(.meta) { line-height: 23px; letter-spacing: .02em; }
:lang(ja) .bio, :lang(zh) .bio { line-height: 29px; letter-spacing: .03em; }
:lang(ja) dd, :lang(zh) dd { letter-spacing: .02em; }
:lang(ja) .bio, :lang(ja) .panel p, :lang(ja) .panel h3 { word-break: auto-phrase; }

/* ---------------------------------------------------------------- About (§1.3.6; r11 home pass, direction A) */
/* a short letter beside a rail of facts */
.about { margin-top: 80px; }
.about-b { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr); gap: 48px; margin-top: 24px; }
.bio { font-size: 16px; line-height: 26px; color: var(--ink-2); text-wrap: pretty; }
.bio p + p { margin-top: 14px; }
.bio .lede { font-size: 22px; line-height: 30px; font-weight: 500; color: var(--ink-hot); text-wrap: balance; }
.about .facts { display: flex; flex-direction: column; font-size: 15px; line-height: 22px; }
.about .facts > div { padding: 16px 0; border-top: 1px solid rgba(0,0,0,.6); box-shadow: inset 0 1px 0 rgba(255,255,255,.05); }
.about .facts > div:first-child { padding-top: 6px; border-top: 0; box-shadow: none; }
.about dt { margin-bottom: 6px; line-height: 16px; }
.about dd { color: var(--ink); font-weight: 500; text-wrap: pretty; }
.about dd .fv { display: block; }
.about dd .fd { display: block; margin-top: 2px; font-weight: 400; color: var(--ink-3); }
.about .langs { display: grid; grid-template-columns: auto 1fr; gap: 4px 14px; font-weight: 400; }
/* the language names stay at 400: 日本語 / 中国語 at 500 would pull in the full 500 JA file on the home page (the dial owns those glyphs) */
.about .langs .ln { color: var(--ink-hot); }
.about .langs .lv { font-weight: 400; color: var(--ink-3); }
:lang(ja) .bio .lede, :lang(zh) .bio .lede { line-height: 32px; letter-spacing: .02em; font-feature-settings: "palt"; }

/* ---------------------------------------------------------------- Elsewhere (§1.3.7; r11: one card with a screenshot) */
.elsewhere { margin-top: 64px; }
.gw {
  display: grid; grid-template-columns: 264px minmax(0, 1fr); align-items: center; gap: 24px; margin-top: 24px;
  padding: 14px 24px 14px 14px; border-radius: 16px; color: var(--ink);
}
.gw-img { display: block; overflow: hidden; border-radius: 10px; background: var(--well); box-shadow: inset 0 0 0 1px rgba(0,0,0,.6); }
.gw-img picture, .gw-img img { display: block; width: 100%; height: auto; }
.gw-img img { opacity: .92; }
.gw-txt { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.gw-t { display: flex; align-items: center; gap: 8px; font-size: 19px; line-height: 26px; font-weight: 600; }
.gw-d { font-size: 15px; line-height: 23px; color: var(--ink-2); text-wrap: pretty; }
.gw-u { margin-top: 2px; letter-spacing: .04em; }
.gw-a { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--ink-yr); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.gw:hover, .gw:focus-visible { box-shadow: var(--sh-face-hover); }
.gw:hover .gw-t, .gw:focus-visible .gw-t { color: var(--cyan); }
.gw:hover .gw-a, .gw:focus-visible .gw-a { stroke: var(--cyan); }
.gw:focus-visible { outline: var(--focus); outline-offset: 4px; }

/* ---------------------------------------------------------------- phone and between (§1.4, §1.5) */
@media (max-width: 1199px) {
  .work { margin-top: 20px; }
  /* In the one-column layouts About and Elsewhere start far below the first screen. Skipping their layout until they
     come near keeps the r11 letter (four times the old bio) out of the first paint and out of a language switch's
     frame, and their text's CJK glyphs are fetched only when they are about to show. */
  .about, .elsewhere { content-visibility: auto; contain-intrinsic-size: auto 1100px; }
  .elsewhere { contain-intrinsic-size: auto 560px; }
}
@media (max-width: 671px) {
  .work { grid-template-columns: 1fr; gap: 16px; }
  .hero .txt { padding: 16px 18px 18px 18px; }
  .hero h3 { font-size: 21px; line-height: 27px; }
  .hero .meta, .hero .desc { font-size: 14.5px; line-height: 22px; }
  .panel .txt { padding: 14px 18px 16px 18px; }
  .hero .txt { padding: 16px 18px 18px 18px; }
  .about { margin-top: 56px; }
  .about-b { grid-template-columns: minmax(0, 1fr); gap: 28px; margin-top: 18px; }
  .bio { font-size: 15px; line-height: 25px; }
  .bio .lede { font-size: 20px; line-height: 28px; }
  :lang(ja) .bio, :lang(zh) .bio { line-height: 27px; }
  :lang(ja) .bio .lede, :lang(zh) .bio .lede { line-height: 30px; }
  .elsewhere { margin-top: 48px; }
  .gw { grid-template-columns: minmax(0, 1fr); gap: 14px; margin-top: 18px; padding: 12px 12px 16px; }
  .gw-txt { padding: 0 6px; }
}
@media (min-width: 672px) and (max-width: 1199px) {
  .foot { margin-top: 56px; }
}

@media (forced-colors: active) {
  .gw { border: 1px solid ButtonText; }
  .panel:has(h3 a:focus-visible) { outline-color: Highlight; }
}

/* dial.css: the language dock (build spec v2 §1.3.10, §1.4), the language control without JS (three plain links in the
   dock's place, §4.6), and the dial (§3.4): the Round 9 prototype's CSS (design-lab/r9/dial/preview.html), scoped
   under .lw, with the R8 hover tag and the R8 forced-colours rules. js/v2/dial.js mounts it into .langdock. */
.langdock { position: fixed; z-index: 10; left: 28px; bottom: 28px; }
.langs ul { display: flex; flex-direction: column; gap: 4px; list-style: none; }
.langs a {
  display: block; padding: 2px 4px; border-radius: 4px; font-size: 14px; line-height: 20px; font-weight: 500; color: var(--ink-3);
}
.langs a:lang(ja) { font-family: var(--f-cjk-ja); }
.langs a:lang(zh) { font-family: var(--f-cjk-zh); }
.langs a:hover { color: var(--cyan); }
.langs a[aria-current="page"] { color: var(--ink-hot); text-decoration: underline; text-decoration-color: var(--cyan); text-underline-offset: 4px; }
/* with JS the dial takes the dock (after the page's load event); the links hold its place unseen until then, and come
   back after 4 s if the dial never mounts */
.js .langdock:not(.dial) .langs { animation: langsWait 0s 4s backwards; }
@keyframes langsWait { from, to { visibility: hidden; } }
.langdock.dial { width: 56px; height: 56px; }
/* the dock stays with the card when the composition is centred (base.css --page-l): 84 px left of the card's edge,
   28 px from the window's edge at 1440 and below, as the board has it */
@media (min-width: 1200px) {
  .langdock { left: max(28px, calc(var(--page-l) - 84px)); }
}

@media (max-width: 1199px) {
  .langdock { left: auto; bottom: auto; top: 8px; right: 16px; height: 44px; display: flex; align-items: center; }
  .langs ul { flex-direction: row; gap: 2px; }
  .langs a { padding: 12px 4px; font-size: 13px; line-height: 20px; }
  .langdock.dial { width: 44px; height: 44px; display: block; }
}

@media (forced-colors: active) {
  .langs a[aria-current="page"] { text-decoration-color: currentColor; }
}

/* ======================================================================================
   THE DIAL (Round 9 prototype)
   ====================================================================================== */
.lw {
  position: absolute; left: 0; top: 0; width: var(--hub); height: var(--hub); --hub: 56px; --S: 248px;
  --o-wedge: 240ms; --o-stag: 40ms; --o-lab: 150ms; --o-ring: 300ms; --c-fold: 170ms;
  --wedge: rgba(15,26,35,.96); --edge: rgba(231,241,247,.12); --mute: #A9BAC6; --cyl: #C8FBFF;
  color: var(--ink);
}
.lw.ph { --hub: 44px; }
.lw .f-en { font-family: var(--f-en); }
.lw .f-ja { font-family: var(--f-cjk-ja); }
.lw .f-zh { font-family: var(--f-cjk-zh); }
.lw button { font: inherit; -webkit-tap-highlight-color: transparent; color: inherit; }
.lw button:focus { outline: none; }
/* every wheel layer is a square centred on the hub */
.lw .sq { position: absolute; left: calc(var(--hub) / 2 - var(--S) / 2); top: calc(var(--hub) / 2 - var(--S) / 2); width: var(--S); height: var(--S); pointer-events: none; }
.lw .sq > svg { display: block; width: 100%; height: 100%; overflow: visible; }

/* the scrim: a fixed layer under the dock, centred on the hub (dial.js writes its gradient) */
.lw-scrim { position: fixed; inset: 0; z-index: 8; pointer-events: none; opacity: 0; transition: opacity 200ms linear 60ms; }
.lw-scrim.on { opacity: 1; transition: opacity 220ms linear; }

/* hub: the helmet-ring button (R8 material) */
.lw-hub {
  position: absolute; inset: 0; z-index: 6; padding: 0; border: 0; border-radius: 50%; cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none;
  background: radial-gradient(circle at 50% 40%, #0e171f 0, #121c25 44%, #18242e 76%, #1e2b36 100%);
  box-shadow: inset 0 0 0 1px rgba(6,216,232,.26), inset 0 1px 0 rgba(255,255,255,.08), inset 0 3px 7px rgba(0,0,0,.5), 0 3px 0 #05080b, 0 8px 14px -6px rgba(0,0,0,.7);
  transition: box-shadow .2s ease-out, transform .12s ease-out;
}
.lw-hub:hover, .lw.open .lw-hub, .lw.press .lw-hub, .lw.drag .lw-hub { box-shadow: inset 0 0 0 1px rgba(6,216,232,.55), inset 0 1px 0 rgba(255,255,255,.1), inset 0 3px 7px rgba(0,0,0,.45), 0 3px 0 #05080b, 0 8px 14px -6px rgba(0,0,0,.7); }
.lw.press .lw-hub { transform: translateY(1.5px) scale(.97); }
.lw.drag .lw-hub { transform: translateY(1px); }
.lw .lw-hub:focus-visible { outline: 2px solid var(--cyan); outline-offset: 6px; }
@keyframes thunk { 0% { transform: scale(1); } 30% { transform: scale(.92); } 70% { transform: scale(1.025); } 100% { transform: scale(1); } }
.lw.thunk .lw-hub { animation: thunk 220ms cubic-bezier(.3,.6,.3,1); }
.lw .mark { position: absolute; inset: 0; display: block; --kr: 1; pointer-events: none; }
.lw.ph .mark { --kr: 1.15; }
.lw .mark svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.lw .m-halo { fill: none; stroke: var(--cyan); stroke-width: calc(var(--kr) * 4.5px); opacity: .13; transition: opacity .2s; }
.lw .m-rim { fill: none; stroke: var(--cyan); stroke-width: calc(var(--kr) * 1.7px); transition: stroke .2s; }
.lw-hub:hover .m-halo, .lw.open .m-halo, .lw.drag .m-halo { opacity: .3; }
.lw-hub:hover .m-rim, .lw.open .m-rim, .lw.drag .m-rim { stroke: #5FEAF4; }
.lw .m-det { fill: rgba(231,241,247,.3); transition: fill .2s; }
.lw.open .m-det, .lw.drag .m-det, .lw-hub:hover .m-det { fill: rgba(231,241,247,.55); }
@keyframes detF { 0% { fill: #E6FEFF; } 100% { fill: rgba(231,241,247,.55); } }
.lw .m-det.flash { animation: detF 260ms ease-out; }
.lw .m-ptr-a { fill: none; stroke: var(--cyl); stroke-width: calc(var(--kr) * 2.3px); stroke-linecap: round; }
.lw .m-ptr-d { fill: var(--cyan); transform-box: fill-box; transform-origin: center; }
@keyframes land { 0%, 100% { transform: scale(1); } 40% { transform: scale(1.75); fill: #E6FEFF; } }
.lw .m-ptr-d.land { animation: land 240ms cubic-bezier(.3,.7,.3,1); }
.lw .code { position: absolute; left: 0; right: 0; top: 50%; text-align: center; line-height: 1; color: #EAF7FA; font-weight: 600; transform: translateY(-50%); pointer-events: none; }
.lw .code.f-en { font-family: var(--f-display); font-size: 10px; font-weight: 700; letter-spacing: .06em; text-indent: .06em; }
.lw .code.f-ja, .lw .code.f-zh { font-size: 13px; }
.lw.ph .code.f-en { font-size: 9px; }
.lw.ph .code.f-ja, .lw.ph .code.f-zh { font-size: 11.5px; }
@keyframes codeIn { from { opacity: 0; transform: translateY(calc(-50% + 5px)); } }
.lw .code.in { animation: codeIn 190ms cubic-bezier(.2,.7,.3,1); }
.lw .rip { position: absolute; left: -6px; top: -6px; right: -6px; bottom: -6px; z-index: 5; border-radius: 50%; border: 1.5px solid var(--cyan); opacity: 0; pointer-events: none; }
@keyframes rip { from { opacity: .9; transform: scale(1); } to { opacity: 0; transform: scale(1.55); } }
.lw .rip.go { animation: rip 400ms cubic-bezier(.2,.7,.3,1); }

/* the tag (R8, Q15): hover or keyboard focus on the closed hub, after 120 ms; never on touch */
.lw-tag {
  position: absolute; z-index: 6; left: 0; bottom: calc(100% + 14px); display: flex; align-items: center; gap: 8px; white-space: nowrap;
  padding: 5px 10px; border-radius: 6px; background: #0f1a23; border: 1px solid rgba(231,241,247,.12); color: #C9D6DF;
  font-size: 12px; line-height: 16px; font-weight: 500; opacity: 0; transform: translateY(4px); pointer-events: none; transition: opacity .12s, transform .12s;
}
.lw-tag i { width: 3px; height: 3px; border-radius: 50%; background: rgba(231,241,247,.3); }
.lw:not(.open):not(.drag) .lw-hub:hover ~ .lw-tag, .lw:not(.open) .lw-hub:focus-visible ~ .lw-tag { opacity: 1; transform: none; transition-delay: .12s; }
.lw.ph .lw-tag { left: auto; right: 0; bottom: auto; top: calc(100% + 12px); transform: translateY(-4px); }
@media (hover: none) { .lw-tag { opacity: 0 !important; } }
.lw.quiet .lw-tag { opacity: 0 !important; transition: none; }

/* wheel: wedges fold out of the hub in a clockwise sweep (--od per wedge), fold back in on close (--cd per wedge) */
.lw .wg {
  z-index: 2; opacity: 0; visibility: hidden; transform: rotate(-12deg) scale(.3);
  transition: transform var(--c-fold) cubic-bezier(.55,0,.8,.2) var(--cd,0ms), opacity 90ms linear calc(var(--cd,0ms) + 80ms), visibility 0s linear calc(var(--cd,0ms) + var(--c-fold));
}
.lw.open .wg {
  opacity: 1; visibility: visible; transform: none;
  transition: transform var(--o-wedge) cubic-bezier(.16,1,.3,1) var(--od), opacity 70ms linear var(--od), visibility 0s linear var(--od);
}
.lw .wg-b { fill: var(--wedge); stroke: var(--edge); stroke-width: 1; }
.lw .wg-f { fill: var(--cyan); opacity: 0; transition: opacity 90ms linear; }
.lw .wg-r { fill: none; stroke: var(--cyan); stroke-width: 2; stroke-linecap: round; stroke-dasharray: 1 2; stroke-dashoffset: 1; transition: stroke-dashoffset 60ms linear, stroke .1s, stroke-width .1s; }
.lw .wg.hot .wg-f { opacity: .11; }
.lw .wg.hot .wg-r { stroke-dashoffset: 0; transition: stroke-dashoffset 130ms cubic-bezier(.2,.8,.3,1), stroke .1s, stroke-width .1s; }
.lw .wg.kf .wg-b { stroke: rgba(6,216,232,.85); stroke-width: 1.5; }
@keyframes fire { 0% { opacity: .11; } 30% { opacity: .42; } 100% { opacity: .2; } }
.lw.fire .wg.pk .wg-f { animation: fire 150ms linear both; }
.lw.fire .wg.pk .wg-r { stroke: #DDFDFF; stroke-width: 3; stroke-dashoffset: 0; }
@keyframes press { 0% { transform: scale(1); } 40% { transform: scale(.965); } 100% { transform: scale(.985); } }
.lw.fire .wg.pk > svg { animation: press 110ms ease-out both; transform-origin: 50% 50%; }
/* the outer track: a hairline that draws out along the fan on open, with a notch at each wedge */
.lw .trk { z-index: 1; }
.lw .trk path { fill: none; stroke: rgba(231,241,247,.2); stroke-width: 1; stroke-dasharray: 1 2; stroke-dashoffset: 1; transition: stroke-dashoffset 150ms cubic-bezier(.5,0,.8,.3) 40ms; }
.lw .trk .nt { stroke: rgba(231,241,247,.32); stroke-dashoffset: 1; transition: stroke-dashoffset 90ms linear 40ms; }
.lw.open .trk path { stroke-dashoffset: 0; transition: stroke-dashoffset var(--o-ring) cubic-bezier(.3,.7,.2,1) 20ms; }
.lw.open .trk .nt { transition: stroke-dashoffset 90ms linear 200ms; }
/* hub-ring segments: faint toward the current language, lit toward the aim */
.lw .hq, .lw .hx { z-index: 7; width: 80px; height: 80px; left: calc(var(--hub) / 2 - 40px); top: calc(var(--hub) / 2 - 40px); opacity: 0; transition: opacity 120ms linear; }
.lw .hq path { fill: none; stroke: rgba(6,216,232,.4); stroke-width: 2.5; stroke-linecap: round; }
.lw .hx path { fill: none; stroke: var(--cyan); stroke-width: 2.75; stroke-linecap: round; }
.lw .hx { transition: opacity 120ms linear, transform 150ms cubic-bezier(.3,1.3,.5,1); }
.lw.open .hq { opacity: 1; transition-delay: 60ms; }
.lw.open.hot .hx { opacity: 1; }
.lw.fire .hx path { stroke: #DDFDFF; }

/* a double click's second press shuts the wheel the first one opened at once (dial.js snapShut) */
.lw.snap .wg, .lw.snap .wg-f, .lw.snap .wg-r, .lw.snap .trk path, .lw.snap .opts, .lw.snap .opt, .lw.snap .hq, .lw.snap .hx, .lw-scrim.snap { transition: none !important; }

/* option labels (the radios). They carry no pointer events: the hit layer resolves direction, like a stick */
.lw .opts { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 4; visibility: hidden; transition: visibility 0s linear 200ms; }
.lw.open .opts { visibility: visible; transition: visibility 0s; }
.lw .opt {
  position: absolute; padding: 0; border: 0; background: transparent; pointer-events: none; white-space: nowrap;
  color: var(--mute); opacity: 0; transform: translate(-50%,-50%) rotate(var(--rot)) scale(.86);
  transition: opacity 70ms linear, transform 120ms cubic-bezier(.5,0,.8,.2), color .12s;
}
.lw.open .opt { opacity: 1; transform: translate(-50%,-50%) rotate(var(--rot)); transition: opacity 110ms linear var(--ld), transform var(--o-lab) cubic-bezier(.2,.9,.3,1) var(--ld), color .12s; }
.lw .opt .lb { display: block; line-height: 1; font-weight: 500; transition: transform 120ms ease-out; }
.lw .opt .lb.f-en { font-size: 14px; }
.lw .opt .lb.f-ja, .lw .opt .lb.f-zh { font-size: 15px; }
.lw.hot .opt { color: #71879A; }
.lw .opt.hot { color: #F4FAFD; }
.lw .opt.hot .lb { transform: scale(1.08); }
.lw.fire .opt { color: #566b7a; }
.lw.fire .opt.pk { color: #FFFFFF; }
.lw.fire .opt.pk .lb { transform: scale(1.14); }
.lw .hit { z-index: 3; }
.lw.open .hit { pointer-events: auto; touch-action: none; }

/* the dial collar: only while pressing / turning. A scale around the knob, a notch per language, the target's name on the ring */
.lw .col { z-index: 5; opacity: 0; transition: opacity 180ms linear; }
.lw.hold .col { opacity: .55; transition: opacity 160ms linear 100ms; }
.lw.drag .col { opacity: 1; transition: opacity 120ms linear; }
.lw .col .sc { fill: none; stroke: rgba(231,241,247,.22); stroke-width: 1; }
.lw .col .tk { stroke: rgba(231,241,247,.45); stroke-width: 1.5; stroke-linecap: round; transition: stroke .1s; }
.lw .col .tk.on { stroke: #F4FAFD; }
.lw .col .tk.cur { stroke: var(--cyan); }
.lw .col .fl { stroke: var(--cyl); stroke-width: 3; stroke-linecap: round; opacity: 0; }
@keyframes notch { 0% { opacity: 1; } 100% { opacity: 0; } }
.lw .col .fl.flash { animation: notch 280ms cubic-bezier(.2,.6,.3,1); }
.lw .col .nd { fill: none; stroke: var(--cyan); stroke-width: 2; stroke-linecap: round; }
.lw .dl { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 5; pointer-events: none; }
.lw .dl span {
  position: absolute; left: 0; top: 0; white-space: nowrap; font-size: 13px; line-height: 1; font-weight: 500; color: var(--ink); opacity: 0; transform-origin: 0 0;
  transition: opacity 120ms linear, color .12s;
}
/* :where() keeps these at the prototype's specificity, so the hide rule below still wins once the drag ends */
:where(.lw) .dl span.on { opacity: .5; }
:where(.lw) .dl span.on.go { opacity: 1; color: var(--cyl); }
.lw:not(.drag) .dl span { opacity: 0; transition: opacity 140ms linear 40ms; }
.lw.lock .dl span.on { opacity: 1; color: #FFFFFF; }

@media (prefers-reduced-motion: reduce) {
  .lw *, .lw { transition-duration: 0s !important; transition-delay: 0s !important; animation: none !important; }
  .lw .opt, .lw .wg { transition: opacity 100ms linear, visibility 0s !important; }
  .lw .wg, .lw.open .wg { transform: none !important; }
  .lw .opt, .lw.open .opt { transform: translate(-50%,-50%) rotate(var(--rot)) !important; }
  .lw-scrim, .lw-scrim.on { transition-duration: 0s; transition-delay: 0s; }
}

/* §5.9: opaque wedges and scrim */
@media (prefers-reduced-transparency: reduce) {
  .lw { --wedge: #0f1a23; }
  .lw-scrim.on { background-color: rgba(7,11,15,.6) !important; }
}

/* forced colours (R8-common.css, R8-motion.css) */
@media (forced-colors: active) {
  .lw-hub, .lw-tag { border: 1px solid ButtonText; }
  .lw .wg-b { fill: Canvas; stroke: CanvasText; }
  .lw .wg-f { fill: none; }
  .lw .wg-r, .lw .hx path { stroke: Highlight; }
  .lw .hq path { stroke: GrayText; }
  .lw .opt { color: ButtonText; }
  .lw .opt:focus-visible { outline: 2px solid Highlight; outline-offset: -2px; }
  .lw .m-rim, .lw .m-ptr-a { stroke: ButtonText; }
  .lw .m-ptr-d, .lw .m-det { fill: ButtonText; }
  .lw .m-halo { display: none; }
  .lw .code { color: ButtonText; }
  .lw .col .nd, .lw .col .tk.cur { stroke: Highlight; }
  .lw .lw-hub:focus-visible { outline: 2px solid Highlight; }
}

/* project.css: the open project (build spec v2 §1.7, a structural default built from existing tokens, Q1; the r11 page
   passes in design-lab/r11/pages and the link rail, pick D, in design-lab/r11/links) and the 404 view (Q20). The frame
   replaces the work column; the card, signature, dock and contact stay where they are. */

.back {
  display: inline-flex; align-items: center; gap: 8px; height: 24px; margin-bottom: 16px; border-radius: 4px;
  font-size: 14px; line-height: 20px; font-weight: 500; color: var(--ink-3);
}
.back .ico { width: 18px; height: 18px; stroke-width: 1.7; }
.back:hover, .back:focus-visible { color: var(--cyan); }
.back:focus-visible { outline: var(--focus); outline-offset: 4px; }

/* The frame is a grid: the loop spans it, the header sits beside the link rail, and .proj-b is display: contents, so
   each block of the body is a row of the frame. Grid auto-placement follows `order`, so the loop, the footage credit,
   the header, the rail and the summary take the first rows, and everything else follows in DOM order. The DOM order
   (header, summary, intro, tools, credit, links, sections) is what a screen reader and Tab meet. js/v2/morph.js reads
   `.proj > .proj-h > h1` and the body's blocks as `.proj-b > *`, which this keeps. */
.proj { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto 24px; align-items: start; border-radius: 18px; }
.proj > .scr { grid-column: 1 / -1; order: -5; aspect-ratio: auto; border-radius: 18px 18px 0 0; }
.proj > .scr video { filter: none; }

.proj-h { grid-column: 2; order: -3; min-width: 0; padding-top: 24px; }
.proj-h h1 { font-size: 28px; line-height: 34px; font-weight: 600; color: var(--ink-hot); text-wrap: balance; }
.proj-h h1:focus { outline: none; }
.proj-h .yr { display: block; margin-top: 6px; line-height: 16px; }
.proj-h .meta { margin-top: 6px; font-size: 15px; line-height: 22px; }

.proj-b { display: contents; font-size: 16px; line-height: 26px; color: var(--ink-2); }
.proj-b > * { grid-column: 2 / 4; min-width: 0; margin-top: 16px; }
.proj-b > :last-child { margin-bottom: 24px; }
.proj-b > .hc { order: -4; margin-top: 14px; }
.proj-b > .sum { order: -1; margin-top: 18px; font-size: 17px; line-height: 28px; color: var(--ink-dd); }
.proj-b > .pl-rail { grid-column: 3; order: -2; margin-top: 26px; }
/* three rows of links or more: the rail also spans the summary, which then sits beside it */
.proj.pl-tall .proj-b > .pl-rail { grid-row: span 2; }
.proj.pl-tall .proj-b > .sum { grid-column: 2; }

.proj-b ul { padding-left: 20px; }
.proj-b li + li { margin-top: 6px; }
.proj-b li::marker { color: var(--sep); }
.proj-b strong { font-weight: 600; color: var(--ink-dd); }
.proj-b .items { list-style: none; padding-left: 0; }
.proj-b .items li + li { margin-top: 12px; }
.proj-b .tools { font-size: 13px; line-height: 20px; letter-spacing: .02em; color: var(--ink-tools); }
.proj-b .tools.parts > span + span::before { content: "/"; opacity: 1; color: var(--sep); }
.proj-b .tools.parts { column-gap: 17px; }
.proj-b .credit { font-size: 13px; line-height: 20px; color: var(--ink-3); }
.proj-b .hc, .proj-b .cap.credit { font-size: 12px; line-height: 18px; letter-spacing: .02em; color: var(--ink-yr); }

/* a fact list (Mushroom Kid): label | value on a desk, stacked on a phone */
.proj-b .facts { border-top: 1px solid rgba(231, 241, 247, .08); }
.proj-b .facts > div { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 16px; padding: 10px 0; border-bottom: 1px solid rgba(231, 241, 247, .08); }
.proj-b .facts dt { padding-top: 3px; font-family: var(--f-display); font-size: 11px; line-height: 20px; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3); }
:lang(ja) .proj-b .facts dt, :lang(zh) .proj-b .facts dt { padding-top: 1px; font-size: 13px; letter-spacing: .08em; text-transform: none; }
:lang(ja) .proj-b .facts dt { font-family: var(--f-cjk-ja); }
:lang(zh) .proj-b .facts dt { font-family: var(--f-cjk-zh); }
.proj-b .facts dd { font-size: 15px; line-height: 23px; color: var(--ink-2); }

/* sections: the section head of §1.3.6, prose, and media under the text that explains it */
.proj-b > .ps { margin-top: 40px; }
.ps > .head + * { margin-top: 18px; }
.ps > * + * { margin-top: 16px; }
/* room between text and media: 30 px on a desk, 24 on a phone; a caption sits 10 px under its picture */
.ps > :is(.fig, .pair, .sprites, .graph) { margin-top: 30px; }
.ps > :is(.fig, .pair, .sprites, .more) + :not(.fig, .pair, .sprites, .graph) { margin-top: 30px; }
.ps > :is(.fig, .pair) + :is(.fig, .pair) { margin-top: 28px; }
.ps > .graph + .more { margin-top: 10px; }
.fig .cap { margin-top: 10px; font-size: 13px; line-height: 20px; color: var(--ink-3); }
.figs > .well + .well { margin-top: 16px; }

/* a media well at the picture's own aspect ratio (set inline), edge to edge across the frame */
.well { position: relative; display: block; margin-left: -24px; margin-right: -24px; overflow: hidden; background: var(--well); aspect-ratio: 16 / 9; }
.well img, .well video { width: 100%; height: 100%; object-fit: contain; }
.well picture { display: block; width: 100%; height: 100%; }
/* the Flipnote colour maps: 16:10 on a desk (the picture contained), its own near-square ratio on a phone */
.well.tall { aspect-ratio: 16 / 10; }
/* Jolyne's loops: whole, at their own ratio, at most 440 px tall on a desk, centred with rounded corners */
.fig.nat { display: flex; justify-content: center; }
.well.nat { width: min(100%, var(--nw)); margin: 0; border-radius: 10px; }
/* two loops side by side (the first two fires) */
.pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.pair .well { margin: 0; border-radius: 8px; aspect-ratio: 800 / 520 !important; }
/* the node graph links to the full-size file */
.well.graph { cursor: zoom-in; }
.more { font-size: 14px; line-height: 20px; }

/* the jam's pixel art at its own size: the cover and the two wide backgrounds across, the sprites in a grid */
.sprites { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.sp { display: grid; place-items: center; min-height: 140px; padding: 12px; border-radius: 6px; background: var(--well); }
.sp img { width: auto; height: auto; max-width: 100%; max-height: 180px; image-rendering: pixelated; }
.sp-hero, .sp-wide { grid-column: 1 / -1; min-height: 0; padding: 0; background: none; }
.sp-hero img, .sp-wide img { width: 100%; max-height: none; }
.sp-hero img { border-radius: 6px; }

/* ---------------------------------------------------------------- links */

/* inline links in the body: cyan on a soft underline, and a small up-right arrow after a link that leaves the site
   (drawn with a mask, so a screen reader hears nothing extra); r11 links lab, inline.css */
.proj-b a.plink:not(.pl-rail a) {
  color: var(--cyan-l); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
  text-decoration-color: rgba(95, 230, 240, .38); border-radius: 3px; text-decoration-skip-ink: auto;
  transition: color .15s, text-decoration-color .15s, background-color .15s, box-shadow .15s;
}
.proj-b a.plink:not(.pl-rail a)[href^="http"]::after {
  content: ""; display: inline-block; width: .58em; height: .58em; margin-left: .2em; vertical-align: .08em;
  background: currentColor; opacity: .6;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17L17 7'/%3E%3Cpath d='M8.5 7H17v8.5'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17L17 7'/%3E%3Cpath d='M8.5 7H17v8.5'/%3E%3C/svg%3E") center / contain no-repeat;
}
.proj-b a.plink:not(.pl-rail a):hover, .proj-b a.plink:not(.pl-rail a):focus-visible {
  color: var(--cyan-p); text-decoration-color: var(--cyan); background: rgba(6, 216, 232, .13); box-shadow: 0 0 0 2px rgba(6, 216, 232, .13);
}
.proj-b a.plink:not(.pl-rail a):hover::after, .proj-b a.plink:not(.pl-rail a):focus-visible::after { background: var(--pink-h); opacity: 1; }
.proj-b a.plink:not(.pl-rail a):focus-visible { outline: var(--focus); outline-offset: 1px; }

/* the link rail (pick D, design-lab/r11/links/d-rail.css, commit 8ba73907): beside the header behind a grooved divider
   with a short pink tick, one row per link, or one row per game (its name, then its links) */
.pl-rail { position: relative; padding: 0 0 0 18px; border-left: 1px solid rgba(0, 0, 0, .6); box-shadow: -1px 0 0 rgba(255, 255, 255, .05); }
.pl-rail::before { content: ""; position: absolute; left: -1px; top: 6px; width: 2px; height: 18px; border-radius: 1px; background: var(--pink); }
.pl-rail ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.proj-b .pl-rail li, .proj-b .pl-rail li + li { margin: 0; }
.pl-rail .plink {
  display: flex; align-items: center; gap: 8px; height: 32px; margin-left: -8px; padding: 0 8px; border-radius: 7px;
  color: var(--ink-dd); font-size: 14px; line-height: 20px; font-weight: 500; white-space: nowrap; text-decoration: none;
  transition: color .2s, background-color .2s;
}
.pl-rail .pl-i { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; color: var(--cyan-l); }
.pl-rail .pl-a { width: 12px; height: 12px; flex: none; margin-left: auto; padding-left: 4px; box-sizing: content-box; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; color: var(--ink-micro); transition: transform .15s, color .15s; }
.pl-rail:has(> .pl-g) { display: grid; grid-template-columns: auto auto; align-items: center; column-gap: 10px; }
.pl-rail .pl-g { display: contents; }
.pl-rail .pl-gl { margin: 0; font-size: 12px; line-height: 16px; color: var(--ink-micro); white-space: nowrap; }
@media (max-width: 671px) { .pl-rail .pl-gl { white-space: normal; } }
.pl-rail .pl-g ul { display: flex; gap: 0 4px; }
.pl-rail .pl-g .pl-a { margin-left: 0; padding-left: 0; }
.pl-rail .plink:hover, .pl-rail .plink:focus-visible { color: var(--ink-hot); background: rgba(6, 216, 232, .07); }
.pl-rail .plink:hover .pl-a, .pl-rail .plink:focus-visible .pl-a { color: var(--pink-h); transform: translate(1px, -1px); }
.pl-rail .plink:focus-visible { outline: var(--focus); outline-offset: 1px; }

:lang(ja) .proj-h h1 { letter-spacing: .02em; font-feature-settings: "palt"; word-break: keep-all; overflow-wrap: anywhere; }
:lang(zh) .proj-h h1 { letter-spacing: .03em; font-feature-settings: "palt"; }
:lang(ja) .proj-b, :lang(zh) .proj-b { line-height: 29px; letter-spacing: .03em; }
:lang(ja) .proj-b > .sum, :lang(zh) .proj-b > .sum { line-height: 30px; }
:lang(ja) .proj-b p, :lang(ja) .proj-b li, :lang(ja) .proj-b dd { word-break: auto-phrase; }

@media (max-width: 671px) {
  .proj { grid-template-columns: 18px minmax(0, 1fr) 18px; }
  .proj-h { padding-top: 20px; }
  .proj-h h1 { font-size: 21px; line-height: 27px; }
  .proj-h .meta { font-size: 14.5px; }
  .proj-b { font-size: 15px; line-height: 25px; }
  .proj-b > *, .proj.pl-tall .proj-b > .sum { grid-column: 2; }
  .proj-b > :last-child { margin-bottom: 20px; }
  .proj-b > .hc { margin-top: 12px; }
  .proj-b > .sum { margin-top: 16px; font-size: 16px; line-height: 26px; }
  :lang(ja) .proj-b, :lang(zh) .proj-b { line-height: 27px; }
  :lang(ja) .proj-b > .sum, :lang(zh) .proj-b > .sum { line-height: 28px; }
  .well { margin-left: -18px; margin-right: -18px; }
  .ps > :is(.fig, .pair, .sprites, .graph) { margin-top: 24px; }
  .ps > :is(.fig, .pair, .sprites, .more) + :not(.fig, .pair, .sprites, .graph) { margin-top: 24px; }
  .ps > :is(.fig, .pair) + :is(.fig, .pair) { margin-top: 20px; }
  .proj-b .facts > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  .well.tall { aspect-ratio: var(--ar); }
  /* Jolyne's loops run edge to edge on a phone, whole, at most 70 % of the screen tall */
  .well.nat { width: auto; max-height: 70vh; margin: 0 -18px; border-radius: 0; }
  .fig.nat { display: block; }
  .pair { gap: 8px; }
  .sprites { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; }
  .sp { min-height: 110px; }
  /* the rail drops under the role line as a compact wrapped block */
  .proj-b > .pl-rail, .proj.pl-tall .proj-b > .pl-rail { grid-column: 2; grid-row: auto; margin-top: 12px; }
  .pl-rail { padding: 8px 0 0; border-left: 0; box-shadow: none; border-top: 1px solid rgba(0, 0, 0, .6); }
  .pl-rail::after { content: ""; position: absolute; left: 0; right: 0; top: 0; border-top: 1px solid rgba(255, 255, 255, .05); }
  .pl-rail::before { left: 0; top: -1px; width: 18px; height: 2px; }
  .pl-rail ul { display: flex; flex-wrap: wrap; gap: 0 14px; }
  .pl-rail .plink { height: 44px; gap: 7px; }
  .pl-rail .pl-a { margin-left: 2px; padding-left: 0; }
  .pl-rail:has(> .pl-g) { grid-template-columns: fit-content(40%) minmax(0, 1fr); column-gap: 14px; }
  .pl-rail .pl-g ul { gap: 0 10px; }
}
@media (prefers-reduced-motion: reduce) { .pl-rail .plink, .pl-rail .pl-a, .proj-b a.plink { transition: none; } }
@media (forced-colors: active) { .pl-rail::before { background: CanvasText; } }

/* 404 (Q20 default): one line and a link home in each language */
.home-links { list-style: none; margin-top: 16px; display: grid; gap: 8px; }
main > h1:not(.nm), .vw > h1:not(.nm) { font-size: 28px; line-height: 34px; font-weight: 600; color: var(--ink-hot); }
main > h1:focus, .vw > h1:focus { outline: none; }
.home-links a { font-size: 16px; line-height: 24px; color: var(--cyan-l); text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(95, 230, 240, .45); }
.home-links a:lang(ja) { font-family: var(--f-ja); }
.home-links a:lang(zh) { font-family: var(--f-zh); }

/* motion.css: what moves (build spec v2 §2.7, §2.8, §3.6 to §3.9): the ring's breath, the grid boost's fade, panel hover
   and preview play, the keys' travel, the Copy tick, the Elsewhere arrow, the hero's pause button and the project morph.
   Reduced motion is handled per item, never with a blanket rule (§3.0). */

/* ---------------------------------------------------------------- the helmet ring breathes (§2.7 item 4) */
.idc::after { animation: keyRim 5.2s ease-in-out infinite; }
.por-bloom { animation: bloom 5.2s ease-in-out infinite; }
@keyframes bloom { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
@keyframes keyRim { 0%, 100% { opacity: .38; } 50% { opacity: .7; } }

/* ---------------------------------------------------------------- grid boost (§3.6.2): light.js sets --mx/--my/opacity */
/* on at once under a move; the 300 ms fade only when it hides after the idle delay (light.js adds .fade) */
.boost.fade { transition: opacity .3s ease-out; }

/* ---------------------------------------------------------------- panels (§3.8): hover (a real pointer) or keyboard focus
   on the title link. :focus-visible rather than :focus-within, so the focus the router returns to a panel after a
   mouse-driven Back doesn't lift it, ring it and play it */
.panel { transition: transform .4s cubic-bezier(.2,.7,.2,1), box-shadow .4s cubic-bezier(.2,.7,.2,1); }
.panel .still { transition: opacity .35s ease, filter .45s; }
.panel .scr video { transition: filter .45s; }
.op-arr { transition: transform .28s cubic-bezier(.3,1.5,.5,1), stroke .2s; }
@keyframes glint { 0% { opacity: 1; background-position: 100% 0; } 80% { opacity: 1; } 100% { opacity: 0; background-position: 0 0; } }

@media (hover: hover) and (pointer: fine) {
  .panel:hover { transform: translateY(-4px); }
  .panel:hover .glint { animation: glint .95s cubic-bezier(.4,0,.2,1) 1; }
  .panel:not(.hero):not(.nopv):hover .still { opacity: 0; }
  .panel:hover .scr video { filter: none; }
  .panel:hover .op-arr { transform: translateX(4px); }
}
.panel:has(h3 a:focus-visible) { transform: translateY(-4px); }
.panel:has(h3 a:focus-visible) .glint { animation: glint .95s cubic-bezier(.4,0,.2,1) 1; }
.panel:not(.hero):not(.nopv):has(h3 a:focus-visible) .still { opacity: 0; }
.panel:has(h3 a:focus-visible) .scr video { filter: none; }
.panel:has(h3 a:focus-visible) .op-arr { transform: translateX(4px); }

/* the hero loop's pause button (Q8): a small key in the screen's corner, over the panel's link */
.vpause {
  position: absolute; right: 12px; bottom: 12px; z-index: 6; display: none; place-items: center;
  width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px; cursor: pointer;
  color: var(--ink-key); background: var(--key); box-shadow: var(--sh-key);
  opacity: .72; transition: opacity .2s, color .2s, box-shadow .12s, transform .12s;
}
.js .vpause { display: grid; }
.vpause .ico { width: 16px; height: 16px; stroke-width: 1.8; }
.vpause .i-pl { display: none; }
.vpause[aria-pressed="true"] .i-pz { display: none; }
.vpause[aria-pressed="true"] .i-pl { display: block; }
.panel:hover .vpause, .vpause:focus-visible, .vpause[aria-pressed="true"] { opacity: 1; }
.vpause:hover, .vpause:focus-visible { color: var(--cyan); box-shadow: var(--sh-key-hover); }
.vpause:active { transform: translateY(2px); box-shadow: var(--sh-key-active); }
.vpause:focus-visible { outline: var(--focus); outline-offset: 4px; }

/* ---------------------------------------------------------------- keys, résumé, Copy, Elsewhere (§3.9) */
.key { transition: color .2s, box-shadow .12s, transform .12s; }
.resume { transition: background .2s, box-shadow .12s, transform .12s; }
.cpy { transition: color .15s, background-color .15s; }
.cpy:active { transform: translateY(1px); }
.cpy.done .i-b { stroke-dasharray: 24; stroke-dashoffset: 0; animation: tick .32s cubic-bezier(.3,.7,.3,1) backwards; }
@keyframes tick { from { stroke-dashoffset: 24; } }
.addr.in { animation: addrIn .12s linear; }
@keyframes addrIn { from { opacity: 0; } }
.gw-t { transition: color .2s; }
.gw-a { transition: transform .3s cubic-bezier(.3,1.4,.5,1), stroke .2s; }
.gw:hover .gw-a, .gw:focus-visible .gw-a { transform: translate(3px, -3px); }

/* ---------------------------------------------------------------- the language switch (§3.5; js/v2/retype.js) */
/* the name is not typed by the retype: js/v2/name.js types the EN name line by line (.typing) and writes in the JA/ZH
   one. The outgoing name fades out over 150 ms from D0 */
.twr .nm:not(.typing) .twg { visibility: visible; }
.twr .nm:not(.typing) .twv { display: none; }
.nm.typing .twg { visibility: hidden; }
.nm.typing .twv { display: block; }
.nm.out { opacity: 0; transition: opacity .15s linear; }

/* ---------------------------------------------------------------- his name written in (§3.2; js/v2/name.js) */
/* while it waits for its data and faces (.pend) and while it writes (.writing) the real text is transparent and the
   ink layer draws it; at the handoff (.done) the ink hides and the real text shows, the same glyph in the same place.
   The card's name has a text shadow, which the browser paints per text fragment (each ruby base, or the ZH line): the
   ink carries the same shadow as a filter on each fragment's group, in text order, so it grows with the ink and
   matches the text's at the handoff. The ink lies under the real text (z-index -1 in the name's stacking context), so
   no shadow falls over the furigana: the kana look the same while the name writes as after the handoff */
.nm.pend .nm-t, .nm.writing .nm-t { color: transparent; text-shadow: none; }
.nm.pend .k { opacity: 0; }
.nm-ink {
  position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; -webkit-user-select: none; user-select: none;
  text-shadow: none; z-index: -1;
}
/* 12 px, not 24: on an SVG group Chrome takes a drop-shadow's blur as the Gaussian's standard deviation, where a
   text-shadow's blur radius is twice it. Measured at 1x, 2x and 3x: the handoff differs by at most 3/255 */
.nm-ink .frag { filter: drop-shadow(0 2px 12px rgba(4,8,12,.55)); }
.nm.done .nm-ink { opacity: 0; visibility: hidden; }

/* ---------------------------------------------------------------- the first load (§3.1; js/v2/load.js) */
/* html.boot (set before first paint by the inline script, once per session) holds every block at its power-on start
   and hides every typed string's visible text; html.boot.go (load.js) plays the sequence. If the script never starts,
   the hold ends 1 s after the stylesheet applies (about 1.1 s after navigation) and the page shows (the failsafe). The text stays in the DOM and the accessibility tree */
@keyframes pw { 0% { opacity: .001; filter: brightness(.35); } 38% { opacity: 1; filter: brightness(1.45) saturate(1.15); } 100% { opacity: 1; filter: none; } }
@keyframes pwHold { from, to { opacity: .001; filter: brightness(.35); } }
@keyframes twHold { from, to { visibility: hidden; } }
@keyframes opHold { from, to { opacity: 0; } }
@keyframes nmHold { from, to { color: transparent; text-shadow: none; } }
.boot .idc, .boot .topbar, .boot .cbar { --bd: 0ms; }
.boot .panel.hero, .boot .back, .boot .proj { --bd: 130ms; }
.boot .panel[data-id="changeling"] { --bd: 210ms; }
.boot .panel[data-id="mushroom"] { --bd: 250ms; }
.boot .panel[data-id="flipnote"] { --bd: 290ms; }
.boot .panel[data-id="jolyne"] { --bd: 330ms; }
.boot .langdock { --bd: 300ms; }
.boot .about, .boot .elsewhere, .boot .foot { --bd: 420ms; }
html.boot:not(.go) :is(.idc, .topbar, .cbar, .panel, .back, .proj, .langdock, .about, .elsewhere, .foot) { animation: pwHold 1s linear; }
html.boot:not(.go) .twg { animation: twHold 1s linear; }
html.boot:not(.go) .tw.r > .twg, html.boot:not(.go) .nm .k { animation: opHold 1s linear; }
html.boot:not(.go) .nm-t { animation: nmHold 1s linear; }
html.boot.go :is(.idc, .topbar, .cbar, .panel, .back, .proj, .langdock, .about, .elsewhere, .foot) {
  animation: pw .52s cubic-bezier(.2,.6,.3,1) var(--bd, 0ms) both;
}

/* reduced motion: the swap is instant, then the new text fades up over 200 ms (two classes so a second switch restarts it) */
html.rmA .twg, html.rmA .nm { animation: rmA .2s ease-out; }
html.rmB .twg, html.rmB .nm { animation: rmB .2s ease-out; }
@keyframes rmA { from { opacity: 0; } }
@keyframes rmB { from { opacity: 0; } }

/* ---------------------------------------------------------------- the project morph (§3.7; js/v2/morph.js, D3v) */
/* classic scrollbars never shift the layout between the two states (review 02 §C fix 2): the gutter is kept from the
   first in-page navigation on, so a short view never drops the scrollbar. Scoped to the router's .nav class rather
   than set at rest: at rest the page always scrolls, so a classic scrollbar is there anyway, and a harness that hides
   scrollbars (the geometry gates) would otherwise measure a reserved but invisible gutter */
html.nav { scrollbar-gutter: stable; }

/* Nothing below applies at rest: the morph adds these for the length of the motion only. */
@property --rh { syntax: "<length>"; inherits: false; initial-value: 400px; }

/* the surface stand-in: the site's .face material, drawn by one fixed element whose box is animated (left, top,
   width, height, radius), so its 1 px rim and radius stay crisp at every size; never a scaled snapshot */
.pm-ghost {
  position: fixed; z-index: 8; pointer-events: none; box-sizing: border-box;
  background-color: var(--face); background-image: var(--grain); box-shadow: var(--sh-face);
}
.pm-ghost::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px; pointer-events: none;
  /* the fixed specular rim, its 60 % stop written in px so it matches the real frame at either end */
  background: linear-gradient(180deg, rgba(226,246,255,.2), rgba(226,246,255,.07) 90px, rgba(226,246,255,.035) calc(var(--rh) * .6), rgba(226,246,255,.02) var(--rh));
  -webkit-mask-image: var(--ring-mask); -webkit-mask-clip: content-box, border-box; -webkit-mask-composite: xor;
  mask-image: var(--ring-mask); mask-clip: content-box, border-box; mask-composite: exclude;
}
/* the real frames while the ghost stands in for their surface */
.pm-hollow { background: none !important; box-shadow: none !important; transform: none !important; transition: none !important; }
.pm-hollow::before, .pm-hollow > .glint { display: none !important; }
.pm-src > .scr { visibility: hidden; }
/* the outgoing text stays above the ghost in the old layer */
.pm-over { position: relative; z-index: 9; }
/* the clicked card's still, riding over a loop that is not playing yet */
.pm-rider { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 3; pointer-events: none; }
/* the travelling title, year and role: real text, re-laid out every frame */
.pm-tt { position: fixed; margin: 0; z-index: 10; pointer-events: none; overflow-wrap: normal; }
.pm-tt.parts { display: flex; }
.pm-tt > div { position: relative; }
/* the card's still held off while its loop lands */
.pm-nostill .scr .still { opacity: 0 !important; transition: none !important; }
/* the one accent: a 3 px slanted cyan blade that rewrites the header */
.pm-blade { position: fixed; z-index: 11; width: 3px; pointer-events: none; background: var(--cyan, #06d8e8); }

/* ---------------------------------------------------------------- reduced motion, item by item */
@media (prefers-reduced-motion: reduce) {
  .idc::after, .por-bloom { animation: none; }
  .boost.fade { transition: none; }
  .panel, .panel .still, .panel .scr video, .op-arr { transition: none; }
  .panel:hover, .panel:has(h3 a:focus-visible) { transform: none; }
  .panel:hover .glint, .panel:has(h3 a:focus-visible) .glint { animation: none; }
  .panel:hover .op-arr, .panel:has(h3 a:focus-visible) .op-arr { transform: none; }
  .key, .resume, .cpy, .gw-t, .gw-a, .vpause { transition: none; }
  .key:active, .resume:active, .cpy:active, .vpause:active { transform: none; }
  .cpy.done .i-b, .addr.in { animation: none; }
  .nm.out { transition: none; }
  .gw:hover .gw-a, .gw:focus-visible .gw-a { transform: none; }
}

@media (forced-colors: active) {
  .vpause { border: 1px solid ButtonText; }
}
