on master help sign in
Pass standard CSS properties through generically
8321f1biko
crates/htmlang-core/src/codegen.rs+14−579
@@ -1351,113 +1351,14 @@ fn generate_node(
1351 }
1351 }
1352}
1352}
1353
1353
1354−/// HTML attributes that are passed through to the HTML tag rather than converted to CSS.
1355−const HTML_PASSTHROUGH_ATTRS: &[&str] = &[
1356− "type",
1357− "placeholder",
1358− "name",
1359− "value",
1360− "disabled",
1361− "required",
1362− "checked",
1363− "for",
1364− "action",
1365− "method",
1366− "autocomplete",
1367− "min",
1368− "max",
1369− "step",
1370− "pattern",
1371− "maxlength",
1372− "rows",
1373− "cols",
1374− "multiple",
1375− "alt",
1376− "role",
1377− "tabindex",
1378− "title",
1379− "autofocus",
1380− // Media
1381− "controls",
1382− "autoplay",
1383− "loop",
1384− "muted",
1385− "playsinline",
1386− "poster",
1387− "preload",
1388− // Image optimization
1389− "loading",
1390− "decoding",
1391− // Media src (explicit attribute form)
1392− "src",
1393− // New element attributes
1394− "datetime",
1395− "media",
1396− "sizes",
1397− "srcset",
1398− "list",
1399− // Details
1400− "open",
1401− // Form
1402− "novalidate",
1403− // Progress/Meter
1404− "low",
1405− "high",
1406− "optimum",
1407− // Table
1408− "colspan",
1409− "rowspan",
1410− "scope",
1411− // Popover API
1412− "popover",
1413− "popovertarget",
1414− "popovertargetaction",
1415− // Modern form/input hints
1416− "inputmode",
1417− "enterkeyhint",
1418− // Performance hints
1419− "fetchpriority",
1420− "blocking",
1421− // Global attrs
1422− "translate",
1423− "spellcheck",
1424− // ARIA live regions
1425− "aria-live",
1426− "aria-atomic",
1427− "aria-relevant",
1428−];
1429−
1430−/// Boolean HTML attributes (rendered without a value, e.g., `<input disabled>`).
1431−const BOOLEAN_HTML_ATTRS: &[&str] = &[
1432− "disabled",
1433− "required",
1434− "checked",
1435− "multiple",
1436− "controls",
1437− "autoplay",
1438− "loop",
1439− "muted",
1440− "playsinline",
1441− "open",
1442− "novalidate",
1443− "autofocus",
1444− "defer",
1445− "async",
1446− "nomodule",
1447− // Popover
1448− "popover",
1449−];
1450
1354
1451fn emit_html_passthrough_attrs(out: &mut String, attrs: &[Attribute]) {
1355fn emit_html_passthrough_attrs(out: &mut String, attrs: &[Attribute]) {
1452 for attr in attrs {
1356 for attr in attrs {
1453 let key = attr.key.as_str();
1357 let key = attr.key.as_str();
1454− let is_passthrough = HTML_PASSTHROUGH_ATTRS.contains(&key)
1358+ if !crate::vocab::is_html_passthrough(key) {
1455− || key.starts_with("aria-")
1456− || key.starts_with("data-");
1457− if !is_passthrough {
1458 continue;
1359 continue;
1459 }
1360 }
1460− if BOOLEAN_HTML_ATTRS.contains(&key) && attr.value.is_none() {
1361+ if crate::vocab::BOOLEAN_HTML_ATTRS.contains(&key) && attr.value.is_none() {
1461 out.push(' ');
1362 out.push(' ');
1462 out.push_str(key);
1363 out.push_str(key);
1463 } else if let Some(val) = &attr.value {
1364 } else if let Some(val) = &attr.value {
@@ -2706,16 +2607,6 @@ fn attrs_to_css(
2706 },
2607 },
2707
2608
2708 // Style
2609 // Style
2709− "background" => {
2710− if let Some(v) = val {
2711− push_css(&mut css, "background", v);
2712− }
2713− }
2714− "color" => {
2715− if let Some(v) = val {
2716− push_css(&mut css, "color", v);
2717− }
2718− }
2719 "border" => {
2610 "border" => {
2720 if let Some(v) = val {
2611 if let Some(v) = val {
2721 let parts: Vec<&str> = v.splitn(2, ' ').collect();
2612 let parts: Vec<&str> = v.splitn(2, ' ').collect();
@@ -2776,28 +2667,8 @@ fn attrs_to_css(
2776 push_css(&mut css, "font-family", v);
2667 push_css(&mut css, "font-family", v);
2777 }
2668 }
2778 }
2669 }
2779− "transition" => {
2780− if let Some(v) = val {
2781− push_css(&mut css, "transition", v);
2782− }
2783− }
2784− "cursor" => {
2785− if let Some(v) = val {
2786− push_css(&mut css, "cursor", v);
2787− }
2788− }
2789− "opacity" => {
2790− if let Some(v) = val {
2791− push_css(&mut css, "opacity", v);
2792− }
2793− }
2794
2670
2795 // Typography
2671 // Typography
2796− "text-align" => {
2797− if let Some(v) = val {
2798− push_css(&mut css, "text-align", v);
2799− }
2800− }
2801 "line-height" => {
2672 "line-height" => {
2802 if let Some(v) = val {
2673 if let Some(v) = val {
2803 push_css(&mut css, "line-height", &css_line_height(v));
2674 push_css(&mut css, "line-height", &css_line_height(v));
@@ -2808,28 +2679,8 @@ fn attrs_to_css(
2808 push_css(&mut css, "letter-spacing", &css_px(v));
2679 push_css(&mut css, "letter-spacing", &css_px(v));
2809 }
2680 }
2810 }
2681 }
2811− "text-transform" => {
2812− if let Some(v) = val {
2813− push_css(&mut css, "text-transform", v);
2814− }
2815− }
2816− "white-space" => {
2817− if let Some(v) = val {
2818− push_css(&mut css, "white-space", v);
2819− }
2820− }
2821
2682
2822 // Overflow & positioning
2683 // Overflow & positioning
2823− "overflow" => {
2824− if let Some(v) = val {
2825− push_css(&mut css, "overflow", v);
2826− }
2827− }
2828− "position" => {
2829− if let Some(v) = val {
2830− push_css(&mut css, "position", v);
2831− }
2832− }
2833 "top" => {
2684 "top" => {
2834 if let Some(v) = val {
2685 if let Some(v) = val {
2835 push_css(&mut css, "top", &css_px(v));
2686 push_css(&mut css, "top", &css_px(v));
@@ -2850,37 +2701,10 @@ fn attrs_to_css(
2850 push_css(&mut css, "left", &css_px(v));
2701 push_css(&mut css, "left", &css_px(v));
2851 }
2702 }
2852 }
2703 }
2853− "z-index" => {
2854− if let Some(v) = val {
2855− push_css(&mut css, "z-index", v);
2856− }
2857− }
2858
2704
2859 // Display & visibility
2705 // Display & visibility
2860− "display" => {
2861− if let Some(v) = val {
2862− push_css(&mut css, "display", v);
2863− }
2864− }
2865− "visibility" => {
2866− if let Some(v) = val {
2867− push_css(&mut css, "visibility", v);
2868− }
2869− }
2870 "hidden" => push_css(&mut css, "display", "none"),
2706 "hidden" => push_css(&mut css, "display", "none"),
2871
2707
2872− // Transform & filters
2873− "transform" => {
2874− if let Some(v) = val {
2875− push_css(&mut css, "transform", v);
2876− }
2877− }
2878− "backdrop-filter" => {
2879− if let Some(v) = val {
2880− push_css(&mut css, "backdrop-filter", v);
2881− }
2882− }
2883−
2884 // Effects
2708 // Effects
2885 "shadow" => {
2709 "shadow" => {
2886 if let Some(v) = val {
2710 if let Some(v) = val {
@@ -2942,20 +2766,6 @@ fn attrs_to_css(
2942 }
2766 }
2943 }
2767 }
2944
2768
2945− // Animation
2946− "animation" => {
2947− if let Some(v) = val {
2948− push_css(&mut css, "animation", v);
2949− }
2950− }
2951−
2952− // Aspect ratio
2953− "aspect-ratio" => {
2954− if let Some(v) = val {
2955− push_css(&mut css, "aspect-ratio", v);
2956− }
2957− }
2958−
2959 // CSS containment for rendering performance
2769 // CSS containment for rendering performance
2960 "contain" => {
2770 "contain" => {
2961 if let Some(v) = val {
2771 if let Some(v) = val {
@@ -3080,18 +2890,6 @@ fn attrs_to_css(
3080 }
2890 }
3081 }
2891 }
3082
2892
3083− // Scroll snap
3084− "scroll-snap-type" => {
3085− if let Some(v) = val {
3086− push_css(&mut css, "scroll-snap-type", v);
3087− }
3088− }
3089− "scroll-snap-align" => {
3090− if let Some(v) = val {
3091− push_css(&mut css, "scroll-snap-align", v);
3092− }
3093− }
3094−
3095 // Margin
2893 // Margin
3096 "margin" => {
2894 "margin" => {
3097 if let Some(v) = val {
2895 if let Some(v) = val {
@@ -3109,125 +2907,10 @@ fn attrs_to_css(
3109 }
2907 }
3110 }
2908 }
3111
2909
3112− // Filter
3113− "filter" => {
3114− if let Some(v) = val {
3115− push_css(&mut css, "filter", v);
3116− }
3117− }
3118−
3119− // Object fit/position (for images)
3120− "object-fit" => {
3121− if let Some(v) = val {
3122− push_css(&mut css, "object-fit", v);
3123− }
3124− }
3125− "object-position" => {
3126− if let Some(v) = val {
3127− push_css(&mut css, "object-position", v);
3128− }
3129− }
3130−
3131− // Text shadow
3132− "text-shadow" => {
3133− if let Some(v) = val {
3134− push_css(&mut css, "text-shadow", v);
3135− }
3136− }
3137−
3138− // Text overflow
3139− "text-overflow" => {
3140− if let Some(v) = val {
3141− push_css(&mut css, "text-overflow", v);
3142− }
3143− }
3144−
3145− // Interaction
3146− "pointer-events" => {
3147− if let Some(v) = val {
3148− push_css(&mut css, "pointer-events", v);
3149− }
3150− }
3151− "user-select" => {
3152− if let Some(v) = val {
3153− push_css(&mut css, "user-select", v);
3154− }
3155− }
3156−
3157− // Flexbox/grid alignment
3158− "justify-content" => {
3159− if let Some(v) = val {
3160− push_css(&mut css, "justify-content", v);
3161− }
3162− }
3163− "align-items" => {
3164− if let Some(v) = val {
3165− push_css(&mut css, "align-items", v);
3166− }
3167− }
3168−
3169− // Flex item order
3170− "order" => {
3171− if let Some(v) = val {
3172− push_css(&mut css, "order", v);
3173− }
3174− }
3175−
3176− // Background extras
3177− "background-size" => {
3178− if let Some(v) = val {
3179− push_css(&mut css, "background-size", v);
3180− }
3181− }
3182− "background-position" => {
3183− if let Some(v) = val {
3184− push_css(&mut css, "background-position", v);
3185− }
3186− }
3187− "background-repeat" => {
3188− if let Some(v) = val {
3189− push_css(&mut css, "background-repeat", v);
3190− }
3191− }
3192−
3193− // Text wrapping
3194− "word-break" => {
3195− if let Some(v) = val {
3196− push_css(&mut css, "word-break", v);
3197− }
3198− }
3199− "overflow-wrap" => {
3200− if let Some(v) = val {
3201− push_css(&mut css, "overflow-wrap", v);
3202− }
3203− }
3204−
3205 // Container queries
2910 // Container queries
3206 "container" => {
2911 "container" => {
3207 push_css(&mut css, "container-type", "inline-size");
2912 push_css(&mut css, "container-type", "inline-size");
3208 }
2913 }
3209− "container-name" => {
3210− if let Some(v) = val {
3211− push_css(&mut css, "container-name", v);
3212− }
3213− }
3214− "container-type" => {
3215− if let Some(v) = val {
3216− push_css(&mut css, "container-type", v);
3217− }
3218− }
3219−
3220− // Overflow axis
3221− "overflow-x" => {
3222− if let Some(v) = val {
3223− push_css(&mut css, "overflow-x", v);
3224− }
3225− }
3226− "overflow-y" => {
3227− if let Some(v) = val {
3228− push_css(&mut css, "overflow-y", v);
3229− }
3230− }
3231
2914
3232 // Inset (shorthand for top/right/bottom/left)
2915 // Inset (shorthand for top/right/bottom/left)
3233 "inset" => {
2916 "inset" => {
@@ -3236,43 +2919,7 @@ fn attrs_to_css(
3236 }
2919 }
3237 }
2920 }
3238
2921
3239− // Accent & caret colors
3240− "accent-color" => {
3241− if let Some(v) = val {
3242− push_css(&mut css, "accent-color", v);
3243− }
3244− }
3245− "caret-color" => {
3246− if let Some(v) = val {
3247− push_css(&mut css, "caret-color", v);
3248− }
3249− }
3250−
3251− // Color scheme & appearance
3252− "color-scheme" => {
3253− if let Some(v) = val {
3254− push_css(&mut css, "color-scheme", v);
3255− }
3256− }
3257− "appearance" => {
3258− if let Some(v) = val {
3259− push_css(&mut css, "appearance", v);
3260− }
3261− }
3262−
3263− // List style
3264− "list-style" => {
3265− if let Some(v) = val {
3266− push_css(&mut css, "list-style", v);
3267− }
3268− }
3269−
3270 // Table
2922 // Table
3271− "border-collapse" => {
3272− if let Some(v) = val {
3273− push_css(&mut css, "border-collapse", v);
3274− }
3275− }
3276 "border-spacing" => {
2923 "border-spacing" => {
3277 if let Some(v) = val {
2924 if let Some(v) = val {
3278 push_css(&mut css, "border-spacing", &css_px(v));
2925 push_css(&mut css, "border-spacing", &css_px(v));
@@ -3280,26 +2927,11 @@ fn attrs_to_css(
3280 }
2927 }
3281
2928
3282 // Text decoration
2929 // Text decoration
3283− "text-decoration" => {
3284− if let Some(v) = val {
3285− push_css(&mut css, "text-decoration", v);
3286− }
3287− }
3288− "text-decoration-color" => {
3289− if let Some(v) = val {
3290− push_css(&mut css, "text-decoration-color", v);
3291− }
3292− }
3293 "text-decoration-thickness" => {
2930 "text-decoration-thickness" => {
3294 if let Some(v) = val {
2931 if let Some(v) = val {
3295 push_css(&mut css, "text-decoration-thickness", &css_px(v));
2932 push_css(&mut css, "text-decoration-thickness", &css_px(v));
3296 }
2933 }
3297 }
2934 }
3298− "text-decoration-style" => {
3299− if let Some(v) = val {
3300− push_css(&mut css, "text-decoration-style", v);
3301− }
3302− }
3303 "text-underline-offset" => {
2935 "text-underline-offset" => {
3304 if let Some(v) = val {
2936 if let Some(v) = val {
3305 push_css(&mut css, "text-underline-offset", &css_px(v));
2937 push_css(&mut css, "text-underline-offset", &css_px(v));
@@ -3312,64 +2944,8 @@ fn attrs_to_css(
3312 push_css(&mut css, "column-width", &css_px(v));
2944 push_css(&mut css, "column-width", &css_px(v));
3313 }
2945 }
3314 }
2946 }
3315− "column-rule" => {
3316− if let Some(v) = val {
3317− push_css(&mut css, "column-rule", v);
3318− }
3319− }
3320−
3321− // Place items/self
3322− "place-items" => {
3323− if let Some(v) = val {
3324− push_css(&mut css, "place-items", v);
3325− }
3326− }
3327− "place-self" => {
3328− if let Some(v) = val {
3329− push_css(&mut css, "place-self", v);
3330− }
3331− }
3332−
3333− // Scroll behavior
3334− "scroll-behavior" => {
3335− if let Some(v) = val {
3336− push_css(&mut css, "scroll-behavior", v);
3337− }
3338− }
3339−
3340− // Resize
3341− "resize" => {
3342− if let Some(v) = val {
3343− push_css(&mut css, "resize", v);
3344− }
3345− }
3346
2947
3347 // New CSS properties
2948 // New CSS properties
3348− "clip-path" => {
3349− if let Some(v) = val {
3350− push_css(&mut css, "clip-path", v);
3351− }
3352− }
3353− "mix-blend-mode" => {
3354− if let Some(v) = val {
3355− push_css(&mut css, "mix-blend-mode", v);
3356− }
3357− }
3358− "background-blend-mode" => {
3359− if let Some(v) = val {
3360− push_css(&mut css, "background-blend-mode", v);
3361− }
3362− }
3363− "writing-mode" => {
3364− if let Some(v) = val {
3365− push_css(&mut css, "writing-mode", v);
3366− }
3367− }
3368− "column-count" => {
3369− if let Some(v) = val {
3370− push_css(&mut css, "column-count", v);
3371− }
3372− }
3373 "column-gap" => {
2949 "column-gap" => {
3374 if let Some(v) = val {
2950 if let Some(v) = val {
3375 push_css(&mut css, "column-gap", &css_px(v));
2951 push_css(&mut css, "column-gap", &css_px(v));
@@ -3380,71 +2956,11 @@ fn attrs_to_css(
3380 push_css(&mut css, "text-indent", &css_px(v));
2956 push_css(&mut css, "text-indent", &css_px(v));
3381 }
2957 }
3382 }
2958 }
3383− "hyphens" => {
3384− if let Some(v) = val {
3385− push_css(&mut css, "hyphens", v);
3386− }
3387− }
3388− "flex-grow" => {
3389− if let Some(v) = val {
3390− push_css(&mut css, "flex-grow", v);
3391− }
3392− }
3393− "flex-shrink" => {
3394− if let Some(v) = val {
3395− push_css(&mut css, "flex-shrink", v);
3396− }
3397− }
3398 "flex-basis" => {
2959 "flex-basis" => {
3399 if let Some(v) = val {
2960 if let Some(v) = val {
3400 push_css(&mut css, "flex-basis", &css_px(v));
2961 push_css(&mut css, "flex-basis", &css_px(v));
3401 }
2962 }
3402 }
2963 }
3403− "isolation" => {
3404− if let Some(v) = val {
3405− push_css(&mut css, "isolation", v);
3406− }
3407− }
3408− "place-content" => {
3409− if let Some(v) = val {
3410− push_css(&mut css, "place-content", v);
3411− }
3412− }
3413− "background-image" => {
3414− if let Some(v) = val {
3415− push_css(&mut css, "background-image", v);
3416− }
3417− }
3418− "font-weight" => {
3419− if let Some(v) = val {
3420− push_css(&mut css, "font-weight", v);
3421− }
3422− }
3423− "font-style" => {
3424− if let Some(v) = val {
3425− push_css(&mut css, "font-style", v);
3426− }
3427− }
3428− "text-wrap" => {
3429− if let Some(v) = val {
3430− push_css(&mut css, "text-wrap", v);
3431− }
3432− }
3433− "will-change" => {
3434− if let Some(v) = val {
3435− push_css(&mut css, "will-change", v);
3436− }
3437− }
3438− "touch-action" => {
3439− if let Some(v) = val {
3440− push_css(&mut css, "touch-action", v);
3441− }
3442− }
3443− "vertical-align" => {
3444− if let Some(v) = val {
3445− push_css(&mut css, "vertical-align", v);
3446− }
3447− }
3448 "scroll-margin" => {
2964 "scroll-margin" => {
3449 if let Some(v) = val {
2965 if let Some(v) = val {
3450 push_css(&mut css, "scroll-margin", &css_px(v));
2966 push_css(&mut css, "scroll-margin", &css_px(v));
@@ -3471,11 +2987,6 @@ fn attrs_to_css(
3471 push_css(&mut css, effective_key, &css_px(v));
2987 push_css(&mut css, effective_key, &css_px(v));
3472 }
2988 }
3473 }
2989 }
3474− "direction" => {
3475− if let Some(v) = val {
3476− push_css(&mut css, "direction", v);
3477− }
3478− }
3479
2990
3480 "content" => {
2991 "content" => {
3481 if let Some(v) = val {
2992 if let Some(v) = val {
@@ -3554,94 +3065,6 @@ fn attrs_to_css(
3554 }
3065 }
3555 }
3066 }
3556
3067
3557− // Grid areas
3558− "grid-template-areas" => {
3559− if let Some(v) = val {
3560− push_css(&mut css, "grid-template-areas", v);
3561− }
3562− }
3563− "grid-area" => {
3564− if let Some(v) = val {
3565− push_css(&mut css, "grid-area", v);
3566− }
3567− }
3568−
3569− // View transitions
3570− "view-transition-name" => {
3571− if let Some(v) = val {
3572− push_css(&mut css, "view-transition-name", v);
3573− }
3574− }
3575−
3576−
3577− // CSS subgrid
3578− "grid-template-columns" => {
3579− if let Some(v) = val {
3580− push_css(&mut css, "grid-template-columns", v);
3581− }
3582− }
3583− "grid-template-rows" => {
3584− if let Some(v) = val {
3585− push_css(&mut css, "grid-template-rows", v);
3586− }
3587− }
3588−
3589− // Scroll-driven animations
3590− "animation-timeline" => {
3591− if let Some(v) = val {
3592− push_css(&mut css, "animation-timeline", v);
3593− }
3594− }
3595− "animation-range" => {
3596− if let Some(v) = val {
3597− push_css(&mut css, "animation-range", v);
3598− }
3599− }
3600− "view-timeline-name" => {
3601− if let Some(v) = val {
3602− push_css(&mut css, "view-timeline-name", v);
3603− }
3604− }
3605− "view-timeline-axis" => {
3606− if let Some(v) = val {
3607− push_css(&mut css, "view-timeline-axis", v);
3608− }
3609− }
3610− "scroll-timeline-name" => {
3611− if let Some(v) = val {
3612− push_css(&mut css, "scroll-timeline-name", v);
3613− }
3614− }
3615− "scroll-timeline-axis" => {
3616− if let Some(v) = val {
3617− push_css(&mut css, "scroll-timeline-axis", v);
3618− }
3619− }
3620−
3621− // Anchor positioning
3622− "anchor-name" => {
3623− if let Some(v) = val {
3624− push_css(&mut css, "anchor-name", v);
3625− }
3626− }
3627− "position-anchor" => {
3628− if let Some(v) = val {
3629− push_css(&mut css, "position-anchor", v);
3630− }
3631− }
3632− "position-area" => {
3633− if let Some(v) = val {
3634− push_css(&mut css, "position-area", v);
3635− }
3636− }
3637−
3638− // initial-letter (drop caps)
3639− "initial-letter" => {
3640− if let Some(v) = val {
3641− push_css(&mut css, "initial-letter", v);
3642− }
3643− }
3644−
3645 // Critical CSS hint — not CSS, handled elsewhere
3068 // Critical CSS hint — not CSS, handled elsewhere
3646 "critical" => {}
3069 "critical" => {}
3647
3070
@@ -3657,6 +3080,18 @@ fn attrs_to_css(
3657 | "sandbox" | "allow" | "allowfullscreen" | "referrerpolicy" | "formaction"
3080 | "sandbox" | "allow" | "allowfullscreen" | "referrerpolicy" | "formaction"
3658 | "formmethod" | "formtarget" | "target" | "autofocus" => {}
3081 | "formmethod" | "formtarget" | "target" | "autofocus" => {}
3659
3082
3083+ // Any other standard CSS property is copied through, with `px`
3084+ // added to bare numbers where the property takes a length.
3085+ key if crate::vocab::is_css_property(key) && !crate::vocab::is_html_passthrough(key) => {
3086+ if let Some(v) = val {
3087+ if crate::vocab::is_length_property(key) {
3088+ push_css(&mut css, key, &css_px_multi(v));
3089+ } else {
3090+ push_css(&mut css, key, v);
3091+ }
3092+ }
3093+ }
3094+
3660 _ => {}
3095 _ => {}
3661 }
3096 }
3662 }
3097 }
crates/htmlang-core/src/lib.rs+1
@@ -1,6 +1,7 @@
1pub mod ast;
1pub mod ast;
2pub mod codegen;
2pub mod codegen;
3pub mod parser;
3pub mod parser;
4+pub mod vocab;
4
5
5#[cfg(test)]
6#[cfg(test)]
6mod codegen_tests;
7mod codegen_tests;
crates/htmlang-core/src/parser.rs+2−336
@@ -3277,337 +3277,6 @@ fn check_undefined_vars(
3277// Attribute parsing
3277// Attribute parsing
3278// ---------------------------------------------------------------------------
3278// ---------------------------------------------------------------------------
3279
3279
3280−const KNOWN_ATTRS: &[&str] = &[
3281− // Layout
3282− "spacing",
3283− "gap",
3284− "padding",
3285− "padding-x",
3286− "padding-y",
3287− "padding-top",
3288− "padding-bottom",
3289− "padding-left",
3290− "padding-right",
3291− "width",
3292− "height",
3293− "min-width",
3294− "max-width",
3295− "min-height",
3296− "max-height",
3297− "center-x",
3298− "center-y",
3299− "align-left",
3300− "align-right",
3301− "align-top",
3302− "align-bottom",
3303− // Style
3304− "background",
3305− "color",
3306− "border",
3307− "border-top",
3308− "border-bottom",
3309− "border-left",
3310− "border-right",
3311− "rounded",
3312− "bold",
3313− "italic",
3314− "underline",
3315− "size",
3316− "font",
3317− "transition",
3318− "cursor",
3319− "opacity",
3320− "text-align",
3321− "line-height",
3322− "letter-spacing",
3323− "text-transform",
3324− "white-space",
3325− "overflow",
3326− "position",
3327− "top",
3328− "right",
3329− "bottom",
3330− "left",
3331− "z-index",
3332− "shadow",
3333− "wrap",
3334− "gap-x",
3335− "gap-y",
3336− // Display & visibility
3337− "display",
3338− "visibility",
3339− // Transform & filters
3340− "transform",
3341− "backdrop-filter",
3342− // Grid
3343− "grid",
3344− "grid-cols",
3345− "grid-rows",
3346− "col-span",
3347− "row-span",
3348− // Container queries
3349− "container",
3350− "container-name",
3351− "container-type",
3352− // Identity
3353− "id",
3354− "class",
3355− // Animation
3356− "animation",
3357− // Form
3358− "type",
3359− "placeholder",
3360− "name",
3361− "value",
3362− "disabled",
3363− "required",
3364− "checked",
3365− "for",
3366− "action",
3367− "method",
3368− "autocomplete",
3369− "min",
3370− "max",
3371− "step",
3372− "pattern",
3373− "maxlength",
3374− "rows",
3375− "cols",
3376− "multiple",
3377− // Accessibility
3378− "alt",
3379− "role",
3380− "tabindex",
3381− "title",
3382− "autofocus",
3383− // CSS: aspect-ratio, outline, logical properties, scroll-snap
3384− "aspect-ratio",
3385− "outline",
3386− "padding-inline",
3387− "padding-block",
3388− "margin-inline",
3389− "margin-block",
3390− "padding-inline-start",
3391− "padding-inline-end",
3392− "padding-block-start",
3393− "padding-block-end",
3394− "margin-inline-start",
3395− "margin-inline-end",
3396− "margin-block-start",
3397− "margin-block-end",
3398− "inset-inline",
3399− "inset-block",
3400− "inset-inline-start",
3401− "inset-inline-end",
3402− "inset-block-start",
3403− "inset-block-end",
3404− "border-inline",
3405− "border-block",
3406− "border-inline-start",
3407− "border-inline-end",
3408− "border-block-start",
3409− "border-block-end",
3410− "border-start-start-radius",
3411− "border-start-end-radius",
3412− "border-end-start-radius",
3413− "border-end-end-radius",
3414− "scroll-margin-inline",
3415− "scroll-margin-block",
3416− "scroll-padding-inline",
3417− "scroll-padding-block",
3418− "inline-size",
3419− "block-size",
3420− "min-inline-size",
3421− "max-inline-size",
3422− "min-block-size",
3423− "max-block-size",
3424− "scroll-snap-type",
3425− "scroll-snap-align",
3426− // Media attributes
3427− "controls",
3428− "autoplay",
3429− "loop",
3430− "muted",
3431− "poster",
3432− "preload",
3433− "loading",
3434− "decoding",
3435− // List
3436− "ordered",
3437− // Media src (explicit attribute form)
3438− "src",
3439− // New elements
3440− "open",
3441− "novalidate",
3442− "low",
3443− "high",
3444− "optimum",
3445− "colspan",
3446− "rowspan",
3447− "scope",
3448− // Margin
3449− "margin",
3450− "margin-x",
3451− "margin-y",
3452− // Filter & object
3453− "filter",
3454− "object-fit",
3455− "object-position",
3456− // Text extras
3457− "text-shadow",
3458− "text-overflow",
3459− // Interaction
3460− "pointer-events",
3461− "user-select",
3462− // Flexbox/grid alignment
3463− "justify-content",
3464− "align-items",
3465− // Flex item
3466− "order",
3467− // Background extras
3468− "background-size",
3469− "background-position",
3470− "background-repeat",
3471− // Text wrapping
3472− "word-break",
3473− "overflow-wrap",
3474− // Asset inlining
3475− "inline",
3476− // Hidden
3477− "hidden",
3478− // Overflow directional
3479− "overflow-x",
3480− "overflow-y",
3481− // Inset shorthand
3482− "inset",
3483− // Modern form theming
3484− "accent-color",
3485− "caret-color",
3486− // Color scheme & appearance
3487− "color-scheme",
3488− "appearance",
3489− // List styling
3490− "list-style",
3491− // Table styling
3492− "border-collapse",
3493− "border-spacing",
3494− // Text decoration variants
3495− "text-decoration",
3496− "text-decoration-color",
3497− "text-decoration-thickness",
3498− "text-decoration-style",
3499− "text-underline-offset",
3500− "column-width",
3501− "column-rule",
3502− // Grid/flex placement
3503− "place-items",
3504− "place-self",
3505− // Scroll behavior
3506− "scroll-behavior",
3507− // Resize
3508− "resize",
3509− // New CSS properties
3510− "clip-path",
3511− "mix-blend-mode",
3512− "background-blend-mode",
3513− "writing-mode",
3514− "column-count",
3515− "column-gap",
3516− "text-indent",
3517− "hyphens",
3518− "flex-grow",
3519− "flex-shrink",
3520− "flex-basis",
3521− "isolation",
3522− "place-content",
3523− "background-image",
3524− "datetime",
3525− "direction",
3526− // New CSS properties (batch 2)
3527− "font-weight",
3528− "font-style",
3529− "text-wrap",
3530− "will-change",
3531− "touch-action",
3532− "vertical-align",
3533− "contain",
3534− "content-visibility",
3535− "scroll-margin",
3536− "scroll-margin-top",
3537− "scroll-margin-bottom",
3538− "scroll-margin-left",
3539− "scroll-margin-right",
3540− "scroll-padding",
3541− "scroll-padding-top",
3542− "scroll-padding-bottom",
3543− "scroll-padding-left",
3544− "scroll-padding-right",
3545− // Iframe/output attrs
3546− "sandbox",
3547− "allow",
3548− "allowfullscreen",
3549− "referrerpolicy",
3550− "formaction",
3551− "formmethod",
3552− "formtarget",
3553− "target",
3554− // Popover API
3555− "popover",
3556− "popovertarget",
3557− "popovertargetaction",
3558− // Modern form/input hints
3559− "inputmode",
3560− "enterkeyhint",
3561− // Performance hints
3562− "fetchpriority",
3563− "blocking",
3564− // Global attrs
3565− "translate",
3566− "spellcheck",
3567− // Script attributes
3568− "defer",
3569− "async",
3570− "crossorigin",
3571− "integrity",
3572− "nomodule",
3573− // Pseudo-element content
3574− "content",
3575− // CSS shorthands
3576− "truncate",
3577− "line-clamp",
3578− "blur",
3579− "backdrop-blur",
3580− "no-scrollbar",
3581− "skeleton",
3582− "gradient",
3583− // Grid areas
3584− "grid-template-areas",
3585− "grid-area",
3586− // View transitions
3587− "view-transition-name",
3588− // Animate shorthand
3589− // Critical CSS hint
3590− "critical",
3591− // CSS subgrid
3592− "grid-template-columns",
3593− "grid-template-rows",
3594− // Scroll-driven animations
3595− "animation-timeline",
3596− "animation-range",
3597− "view-timeline-name",
3598− "view-timeline-axis",
3599− "scroll-timeline-name",
3600− "scroll-timeline-axis",
3601− // Anchor positioning
3602− "anchor-name",
3603− "position-anchor",
3604− "position-area",
3605− // Drop caps
3606− "initial-letter",
3607− // Responsive images
3608− "responsive",
3609−];
3610−
3611/// Attributes that expect purely numeric values (px-based) or values with CSS units.
3280/// Attributes that expect purely numeric values (px-based) or values with CSS units.
3612const NUMERIC_ATTRS: &[&str] = &[
3281const NUMERIC_ATTRS: &[&str] = &[
3613 "spacing",
3282 "spacing",
@@ -4143,11 +3812,8 @@ fn parse_attr_list(
4143 // Warn on unknown attributes
3812 // Warn on unknown attributes
4144 if validate {
3813 if validate {
4145 let base_key = strip_all_prefixes(attr.key.as_str());
3814 let base_key = strip_all_prefixes(attr.key.as_str());
4146− if !KNOWN_ATTRS.contains(&base_key)
3815+ if !crate::vocab::is_known_attribute(base_key) {
4147− && !base_key.starts_with("aria-")
4148− && !base_key.starts_with("data-")
4149− {
4150− let suggestion = suggest_closest(base_key, KNOWN_ATTRS);
3816+ let suggestion = suggest_closest(base_key, &crate::vocab::all_attributes());
4151 let msg = match suggestion {
3817 let msg = match suggestion {
4152 Some(closest) => {
3818 Some(closest) => {
4153 format!(
3819 format!(
crates/htmlang-core/src/vocab.rsnew file+202
@@ -0,0 +1,202 @@
1+//! The attribute vocabulary.
2+//!
3+//! An attribute in `[...]` is one of three things:
4+//! - one of htmlang's own attributes, which mean more than a single CSS
5+//! property (`spacing`, `center-x`, `rounded`, ...), handled in codegen;
6+//! - a standard CSS property, copied into the generated CSS unchanged;
7+//! - an HTML attribute, emitted on the element.
8+
9+/// htmlang's own attributes (those that are neither a CSS property nor an
10+/// HTML attribute).
11+pub const HTMLANG_ATTRIBUTES: &[&str] = &[
12+ "align-bottom", "align-left", "align-right", "align-top", "backdrop-blur", "blur", "bold",
13+ "center-x", "center-y", "col-span", "critical", "gap-x", "gap-y", "gradient", "grid-cols",
14+ "grid-rows", "inline", "italic", "margin-x", "margin-y", "no-scrollbar", "ordered",
15+ "padding-x", "padding-y", "responsive", "rounded", "row-span", "shadow", "skeleton",
16+ "spacing", "truncate", "underline",
17+];
18+
19+/// Standard CSS properties, sorted. Any of these can be written as an
20+/// attribute and is copied into the generated CSS as-is.
21+pub const CSS_PROPERTIES: &[&str] = &[
22+ "accent-color", "align-content", "align-items", "align-self", "all", "anchor-name",
23+ "animation", "animation-composition", "animation-delay", "animation-direction",
24+ "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name",
25+ "animation-play-state", "animation-range", "animation-range-end", "animation-range-start",
26+ "animation-timeline", "animation-timing-function", "appearance", "aspect-ratio",
27+ "backdrop-filter", "backface-visibility", "background", "background-attachment",
28+ "background-blend-mode", "background-clip", "background-color", "background-image",
29+ "background-origin", "background-position", "background-position-x",
30+ "background-position-y", "background-repeat", "background-size", "block-size", "border",
31+ "border-block", "border-block-color", "border-block-end", "border-block-end-color",
32+ "border-block-end-style", "border-block-end-width", "border-block-start",
33+ "border-block-start-color", "border-block-start-style", "border-block-start-width",
34+ "border-block-style", "border-block-width", "border-bottom", "border-bottom-color",
35+ "border-bottom-left-radius", "border-bottom-right-radius", "border-bottom-style",
36+ "border-bottom-width", "border-collapse", "border-color", "border-end-end-radius",
37+ "border-end-start-radius", "border-image", "border-image-outset", "border-image-repeat",
38+ "border-image-slice", "border-image-source", "border-image-width", "border-inline",
39+ "border-inline-color", "border-inline-end", "border-inline-end-color",
40+ "border-inline-end-style", "border-inline-end-width", "border-inline-start",
41+ "border-inline-start-color", "border-inline-start-style", "border-inline-start-width",
42+ "border-inline-style", "border-inline-width", "border-left", "border-left-color",
43+ "border-left-style", "border-left-width", "border-radius", "border-right",
44+ "border-right-color", "border-right-style", "border-right-width", "border-spacing",
45+ "border-start-end-radius", "border-start-start-radius", "border-style", "border-top",
46+ "border-top-color", "border-top-left-radius", "border-top-right-radius", "border-top-style",
47+ "border-top-width", "border-width", "bottom", "box-decoration-break", "box-shadow",
48+ "box-sizing", "break-after", "break-before", "break-inside", "caption-side", "caret-color",
49+ "clear", "clip", "clip-path", "color", "color-scheme", "column-count", "column-fill",
50+ "column-gap", "column-rule", "column-rule-color", "column-rule-style", "column-rule-width",
51+ "column-span", "column-width", "columns", "contain", "contain-intrinsic-block-size",
52+ "contain-intrinsic-height", "contain-intrinsic-inline-size", "contain-intrinsic-size",
53+ "contain-intrinsic-width", "container", "container-name", "container-type", "content",
54+ "content-visibility", "counter-increment", "counter-reset", "counter-set", "cursor",
55+ "direction", "display", "empty-cells", "field-sizing", "filter", "flex", "flex-basis",
56+ "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", "float", "font",
57+ "font-family", "font-feature-settings", "font-kerning", "font-language-override",
58+ "font-optical-sizing", "font-palette", "font-size", "font-size-adjust", "font-stretch",
59+ "font-style", "font-synthesis", "font-variant", "font-variant-alternates",
60+ "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures",
61+ "font-variant-numeric", "font-variant-position", "font-variation-settings", "font-weight",
62+ "forced-color-adjust", "gap", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
63+ "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-start", "grid-row",
64+ "grid-row-end", "grid-row-start", "grid-template", "grid-template-areas",
65+ "grid-template-columns", "grid-template-rows", "hanging-punctuation", "height",
66+ "hyphenate-character", "hyphens", "image-orientation", "image-rendering", "initial-letter",
67+ "inline-size", "inset", "inset-block", "inset-block-end", "inset-block-start",
68+ "inset-inline", "inset-inline-end", "inset-inline-start", "interpolate-size", "isolation",
69+ "justify-content", "justify-items", "justify-self", "left", "letter-spacing", "line-break",
70+ "line-clamp", "line-height", "list-style", "list-style-image", "list-style-position",
71+ "list-style-type", "margin", "margin-block", "margin-block-end", "margin-block-start",
72+ "margin-bottom", "margin-inline", "margin-inline-end", "margin-inline-start", "margin-left",
73+ "margin-right", "margin-top", "mask", "mask-clip", "mask-composite", "mask-image",
74+ "mask-mode", "mask-origin", "mask-position", "mask-repeat", "mask-size", "mask-type",
75+ "math-depth", "math-style", "max-block-size", "max-height", "max-inline-size", "max-width",
76+ "min-block-size", "min-height", "min-inline-size", "min-width", "mix-blend-mode",
77+ "object-fit", "object-position", "offset", "offset-anchor", "offset-distance",
78+ "offset-path", "offset-position", "offset-rotate", "opacity", "order", "orphans", "outline",
79+ "outline-color", "outline-offset", "outline-style", "outline-width", "overflow",
80+ "overflow-anchor", "overflow-block", "overflow-clip-margin", "overflow-inline",
81+ "overflow-wrap", "overflow-x", "overflow-y", "overscroll-behavior",
82+ "overscroll-behavior-block", "overscroll-behavior-inline", "overscroll-behavior-x",
83+ "overscroll-behavior-y", "padding", "padding-block", "padding-block-end",
84+ "padding-block-start", "padding-bottom", "padding-inline", "padding-inline-end",
85+ "padding-inline-start", "padding-left", "padding-right", "padding-top", "page",
86+ "page-break-after", "page-break-before", "page-break-inside", "paint-order", "perspective",
87+ "perspective-origin", "place-content", "place-items", "place-self", "pointer-events",
88+ "position", "position-anchor", "position-area", "position-try", "position-try-fallbacks",
89+ "position-visibility", "print-color-adjust", "quotes", "resize", "right", "rotate",
90+ "row-gap", "ruby-align", "ruby-position", "scale", "scroll-behavior", "scroll-margin",
91+ "scroll-margin-block", "scroll-margin-block-end", "scroll-margin-block-start",
92+ "scroll-margin-bottom", "scroll-margin-inline", "scroll-margin-inline-end",
93+ "scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right",
94+ "scroll-margin-top", "scroll-padding", "scroll-padding-block", "scroll-padding-block-end",
95+ "scroll-padding-block-start", "scroll-padding-bottom", "scroll-padding-inline",
96+ "scroll-padding-inline-end", "scroll-padding-inline-start", "scroll-padding-left",
97+ "scroll-padding-right", "scroll-padding-top", "scroll-snap-align", "scroll-snap-stop",
98+ "scroll-snap-type", "scroll-timeline", "scroll-timeline-axis", "scroll-timeline-name",
99+ "scrollbar-color", "scrollbar-gutter", "scrollbar-width", "shape-image-threshold",
100+ "shape-margin", "shape-outside", "tab-size", "table-layout", "text-align",
101+ "text-align-last", "text-anchor", "text-box", "text-box-edge", "text-box-trim",
102+ "text-combine-upright", "text-decoration", "text-decoration-color", "text-decoration-line",
103+ "text-decoration-skip-ink", "text-decoration-style", "text-decoration-thickness",
104+ "text-emphasis", "text-emphasis-color", "text-emphasis-position", "text-emphasis-style",
105+ "text-indent", "text-justify", "text-orientation", "text-overflow", "text-rendering",
106+ "text-shadow", "text-transform", "text-underline-offset", "text-underline-position",
107+ "text-wrap", "text-wrap-mode", "text-wrap-style", "timeline-scope", "top", "touch-action",
108+ "transform", "transform-box", "transform-origin", "transform-style", "transition",
109+ "transition-behavior", "transition-delay", "transition-duration", "transition-property",
110+ "transition-timing-function", "translate", "unicode-bidi", "user-select", "vertical-align",
111+ "view-timeline", "view-timeline-axis", "view-timeline-inset", "view-timeline-name",
112+ "view-transition-class", "view-transition-name", "visibility", "white-space",
113+ "white-space-collapse", "widows", "width", "will-change", "word-break", "word-spacing",
114+ "writing-mode", "z-index", "zoom",
115+];
116+
117+/// HTML attributes emitted on any element when present.
118+pub const HTML_PASSTHROUGH_ATTRS: &[&str] = &[
119+ "action", "alt", "aria-atomic", "aria-live", "aria-relevant", "autocomplete", "autofocus",
120+ "autoplay", "blocking", "checked", "cols", "colspan", "controls", "datetime", "decoding",
121+ "disabled", "enterkeyhint", "fetchpriority", "for", "high", "inputmode", "list", "loading",
122+ "loop", "low", "max", "maxlength", "media", "method", "min", "multiple", "muted", "name",
123+ "novalidate", "open", "optimum", "pattern", "placeholder", "playsinline", "popover",
124+ "popovertarget", "popovertargetaction", "poster", "preload", "required", "role", "rows",
125+ "rowspan", "scope", "sizes", "spellcheck", "src", "srcset", "step", "tabindex", "title",
126+ "translate", "type", "value",
127+];
128+
129+/// Boolean HTML attributes (rendered without a value, e.g. `<input disabled>`).
130+pub const BOOLEAN_HTML_ATTRS: &[&str] = &[
131+ "disabled", "required", "checked", "multiple", "controls", "autoplay", "loop", "muted",
132+ "playsinline", "open", "novalidate", "autofocus", "defer", "async", "nomodule", "popover",
133+];
134+
135+/// Every HTML attribute htmlang knows, including ones only certain elements
136+/// emit (`href`, `sandbox`, `defer`, ...).
137+pub const HTML_ATTRIBUTES: &[&str] = &[
138+ "abbr", "accept", "action", "allow", "allowfullscreen", "alt", "aria-atomic", "aria-live",
139+ "aria-relevant", "async", "autocomplete", "autofocus", "autoplay", "blocking", "charset",
140+ "checked", "cite", "class", "cols", "colspan", "content", "contenteditable", "controls",
141+ "crossorigin", "datetime", "decoding", "defer", "dir", "disabled", "download", "draggable",
142+ "enctype", "enterkeyhint", "fetchpriority", "for", "form", "formaction", "formmethod",
143+ "formtarget", "headers", "height", "hidden", "high", "href", "hreflang", "http-equiv", "id",
144+ "inert", "inputmode", "integrity", "ismap", "kind", "label", "lang", "list", "loading",
145+ "loop", "low", "max", "maxlength", "media", "method", "min", "multiple", "muted", "name",
146+ "nomodule", "novalidate", "open", "optimum", "pattern", "placeholder", "playsinline",
147+ "popover", "popovertarget", "popovertargetaction", "poster", "preload", "readonly",
148+ "referrerpolicy", "rel", "required", "reversed", "role", "rows", "rowspan", "sandbox",
149+ "scope", "selected", "size", "sizes", "span", "spellcheck", "src", "srcset", "start",
150+ "step", "tabindex", "target", "title", "translate", "type", "usemap", "value", "width",
151+ "wrap",
152+];
153+
154+/// CSS properties whose bare numbers are lengths, so `margin-top 16` means
155+/// `16px`. (Others, like `opacity` or `z-index`, take unitless numbers.)
156+pub fn is_length_property(name: &str) -> bool {
157+ const PREFIXES: &[&str] = &["margin", "padding", "inset", "scroll-margin", "scroll-padding"];
158+ const SUFFIXES: &[&str] = &["-width", "-height", "-radius", "-offset", "-spacing", "gap"];
159+ const EXACT: &[&str] = &[
160+ "top", "right", "bottom", "left", "width", "height", "font-size", "block-size",
161+ "inline-size", "min-block-size", "max-block-size", "min-inline-size", "max-inline-size",
162+ "text-indent", "flex-basis", "perspective", "text-decoration-thickness",
163+ ];
164+ EXACT.contains(&name)
165+ || PREFIXES.iter().any(|p| name.starts_with(p))
166+ || SUFFIXES.iter().any(|s| name.ends_with(s))
167+}
168+
169+pub fn is_css_property(name: &str) -> bool {
170+ CSS_PROPERTIES.binary_search(&name).is_ok()
171+}
172+
173+/// Emitted as an HTML attribute on any element.
174+pub fn is_html_passthrough(name: &str) -> bool {
175+ HTML_PASSTHROUGH_ATTRS.contains(&name) || name.starts_with("aria-") || name.starts_with("data-")
176+}
177+
178+pub fn is_known_attribute(name: &str) -> bool {
179+ HTMLANG_ATTRIBUTES.contains(&name)
180+ || is_css_property(name)
181+ || HTML_ATTRIBUTES.contains(&name)
182+ || name.starts_with("aria-")
183+ || name.starts_with("data-")
184+}
185+
186+/// All known attribute names, for "did you mean" suggestions.
187+pub fn all_attributes() -> Vec<&'static str> {
188+ HTMLANG_ATTRIBUTES
189+ .iter()
190+ .chain(CSS_PROPERTIES)
191+ .chain(HTML_ATTRIBUTES)
192+ .copied()
193+ .collect()
194+}
195+
196+#[cfg(test)]
197+mod tests {
198+ #[test]
199+ fn css_properties_are_sorted() {
200+ assert!(super::CSS_PROPERTIES.windows(2).all(|w| w[0] < w[1]));
201+ }
202+}
tests/snapshots/stress_deeply_nested.html+1−1
@@ -1 +1 @@
1−<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Deeply Nested Stress Test</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--border:#e2e8f0;--radius:8;}@layer htmlang{.a{display:flex;flex-direction:column;gap:20px;padding:24px;}.b{display:flex;flex-direction:column;background:#f0f9ff;border-radius:12px;padding:20px;border:1px solid #bae6fd;}.c{font-weight:bold;font-size:20px;color:#0369a1;}.d{display:flex;flex-direction:row;gap:16px;}.e{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);flex:1;min-width:0;}.f{font-weight:bold;font-size:16px;color:#1e293b;}.g{display:flex;flex-direction:column;gap:8px;}.h{display:flex;flex-direction:column;background:#f1f5f9;border-radius:6px;padding:12px;}.i{font-size:14px;color:#475569;}.j{display:flex;flex-direction:column;gap:4px;}.k{display:flex;flex-direction:column;padding:8px 12px;border-radius:4px;transition:all 0.15s;}.l{font-size:13px;color:#64748b;}.m{display:flex;flex-direction:row;gap:6px;align-items:center;}.n{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#10b981;}.o{display:flex;flex-direction:column;padding:4px 8px;background:#dbeafe;border-radius:4px;}.p{font-size:11px;color:#1d4ed8;}.q{flex-direction:column;display:inline-block;}.r{font-size:10px;color:var(--primary);}.s{display:flex;flex-direction:column;}.t{font-size:9px;color:#93c5fd;}.u{display:flex;flex-direction:column;padding:2px 4px;background:#eff6ff;border-radius:2px;}.v{font-size:8px;color:#bfdbfe;}.w{display:flex;flex-direction:column;padding:8px 12px;border-radius:4px;}.x{display:flex;flex-direction:column;padding:6px;background:#f0fdf4;border-radius:4px;}.y{font-size:12px;color:#166534;}.z{display:flex;flex-direction:row;gap:4px;}.aa{display:flex;flex-direction:column;padding:2px 6px;background:#bbf7d0;border-radius:2px;}.ab{font-size:10px;color:#15803d;}.ac{display:flex;flex-direction:column;padding:2px 6px;background:#fef3c7;border-radius:2px;}.ad{font-size:10px;color:#92400e;}.ae{display:flex;flex-direction:column;gap:12px;}.af,.bk{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.ag{font-weight:bold;font-size:16px;}.ah,.bl{display:flex;flex-direction:column;background:#f8fafc;border-radius:6px;padding:12px;}.ai{display:flex;flex-direction:row;gap:8px;}.aj{display:flex;flex-direction:column;flex:1;min-width:0;background:#eff6ff;border-radius:4px;padding:8px;}.ak{font-size:12px;color:#1d4ed8;font-weight:bold;}.al{display:flex;flex-direction:column;height:60px;background:#dbeafe;border-radius:4px;padding:8px;}.am{font-size:20px;font-weight:bold;color:#1e40af;}.an{display:flex;flex-direction:row;gap:2px;}.ao{display:flex;flex-direction:column;width:4px;height:12px;background:#93c5fd;border-radius:1px;}.ap{display:flex;flex-direction:column;width:4px;height:18px;background:#60a5fa;border-radius:1px;}.aq{display:flex;flex-direction:column;width:4px;height:8px;background:#93c5fd;border-radius:1px;}.ar{display:flex;flex-direction:column;width:4px;height:22px;background:var(--primary);border-radius:1px;}.as{display:flex;flex-direction:column;width:2px;height:2px;border-radius:50%;background:white;}.at{font-size:6px;color:white;}.au{display:flex;flex-direction:column;flex:1;min-width:0;background:#f0fdf4;border-radius:4px;padding:8px;}.av{font-size:12px;color:#166534;font-weight:bold;}.aw{display:flex;flex-direction:column;height:60px;background:#dcfce7;border-radius:4px;padding:8px;}.ax{font-size:20px;font-weight:bold;color:#166534;}.ay{font-size:10px;color:#16a34a;}.az{flex-direction:column;padding:1px 4px;background:#bbf7d0;border-radius:2px;display:inline-block;}.a0{font-size:8px;color:#15803d;}.a1,.ba{display:flex;flex-direction:column;padding:8px;border:1px solid var(--border);border-radius:4px;}.a2{font-size:12px;color:#64748b;}.a3{padding:6px 10px;border-radius:4px;border:1px solid var(--border);width:100%;}.a4{display:flex;flex-direction:column;padding:4px 8px;background:#fef2f2;border-radius:4px;}.a5{font-size:11px;color:#991b1b;}.a6{font-size:10px;color:#dc2626;}.a7{display:flex;flex-direction:column;padding:2px 4px;background:#fee2e2;border-radius:2px;}.a8{font-size:9px;color:#b91c1c;}.a9{display:flex;flex-direction:column;gap:6px;}.bb{font-size:14px;font-weight:bold;color:#1e293b;}.bc{display:flex;flex-direction:column;padding:6px;background:#f8fafc;border-radius:4px;}.bd{display:flex;flex-direction:row;gap:8px;align-items:center;}.be{display:flex;flex-direction:column;width:8px;height:8px;border-radius:2px;background:var(--primary);}.bf{font-size:12px;color:#475569;}.bg{font-size:11px;color:#94a3b8;}.bh{display:flex;flex-direction:column;padding:2px 6px;background:#eff6ff;border-radius:2px;}.bi{display:flex;flex-direction:column;background:#fefce8;border-radius:12px;padding:20px;border:1px solid #fde68a;}.bj{font-weight:bold;font-size:20px;color:#854d0e;}.bm{display:flex;flex-direction:column;padding:10px;border:1px solid var(--border);border-radius:6px;}.bn{font-size:13px;color:#1e293b;}.bo{flex-direction:column;width:80px;height:80px;border-radius:50%;background:var(--border);display:flex;align-items:center;justify-content:center;}.bp{font-size:24px;color:#94a3b8;font-weight:bold;}.bq{flex-direction:column;position:absolute;bottom:0;right:0;width:24px;height:24px;border-radius:50%;background:var(--primary);display:flex;align-items:center;justify-content:center;}.br{font-size:10px;color:white;}.bs{display:flex;flex-direction:column;padding:1px 3px;background:#1e3a5f;border-radius:2px;}.bt{font-size:7px;color:white;}.bu{display:flex;flex-direction:row;gap:8px;align-items:center;padding:6px 8px;border:1px solid var(--border);border-radius:4px;}.bv{font-size:13px;color:#1e293b;flex:1;min-width:0;}.bw{display:flex;flex-direction:column;padding:4px 12px;background:#f1f5f9;border-radius:4px;}.bx{display:flex;flex-direction:row;gap:8px;align-items:center;padding:8px;border-bottom:1px solid var(--border);}.by{font-size:14px;color:#1e293b;flex:1;min-width:0;}.bz{display:flex;flex-direction:column;width:36px;height:20px;border-radius:10px;background:var(--primary);padding:2px;}.b0{display:flex;flex-direction:column;width:16px;height:16px;border-radius:50%;background:white;}.b1{display:flex;flex-direction:column;background:#fdf2f8;border-radius:12px;padding:20px;border:1px solid #fbcfe8;}.b2{font-weight:bold;font-size:20px;color:#9d174d;}.b3{display:flex;flex-direction:column;background:white;border-radius:8px;padding:12px;border:1px solid var(--border);flex:1;min-width:0;}.b4{font-weight:bold;font-size:14px;color:#1e293b;}.b5{display:flex;flex-direction:column;background:#f0fdf4;border-radius:6px;padding:8px;}.b6{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#86efac;border-radius:2px;}.b7{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#4ade80;border-radius:2px;}.b8{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#22c55e;border-radius:2px;}.b9{font-size:11px;color:#16a34a;}.ca{font-size:10px;color:#22c55e;}.cb{display:flex;flex-direction:column;padding:2px 6px;background:#dcfce7;border-radius:2px;}.cc{font-size:9px;color:#15803d;}.cd{font-size:8px;color:#4ade80;}.ce{display:flex;flex-direction:column;padding:1px 3px;background:#bbf7d0;border-radius:1px;}.cf{font-size:7px;color:#166534;}.k:hover,.w:hover{background:var(--border);}.ba:hover{background:#f8fafc;}@media(prefers-color-scheme:dark){.af{background:#1e293b;}.ah{background:#0f172a;}}}</style></head><body><div class="a"><div class="b"><span class="c">Level 1 - App Shell</span><div class="d"><div class="e"><span class="f">Level 2 - Sidebar</span><div class="g"><div class="h"><span class="i">Level 3 - Nav Group</span><div class="j"><div class="k"><span class="l">Level 4 - Nav Item</span><div class="m"><div class="n"></div><div class="o"><span class="p">Level 5 - Badge</span><div class="q"><span class="r">Level 6 - Badge Detail</span><div class="s"><span class="t">Level 7 - Sub Detail</span><div class="u"><span class="v">Level 8 - Deepest Badge</span></div></div></div></div></div></div><div class="w"><span class="l">Level 4 - Second Nav Item</span><div class="x"><span class="y">Level 5 - Status</span><div class="z"><div class="aa"><span class="ab">Level 6 - Online</span></div><div class="ac"><span class="ad">Level 6 - Away</span></div></div></div></div></div></div><div class="h"><span class="i">Level 3 - Second Group</span><div class="j"><div class="w"><span class="l">Settings</span></div><div class="w"><span class="l">Profile</span></div><div class="w"><span class="l">Security</span></div></div></div></div></div><div class="e"><span class="f">Level 2 - Main Content</span><div class="ae"><div class="af"><span class="ag">Level 3 - Dashboard Card</span><div class="ah"><span class="l">Level 4 - Chart Area</span><div class="ai"><div class="aj"><span class="ak">Level 5 - Metric A</span><div class="al"><span class="am">Level 6 - Value</span><div class="s"><span class="r">Level 7 - Trend</span><div class="an"><div class="ao"></div><div class="ap"></div><div class="aq"></div><div class="ar"><div class="as"><span class="at">Level 8 - Spark Dot</span></div></div></div></div></div></div><div class="au"><span class="av">Level 5 - Metric B</span><div class="aw"><span class="ax">Level 6 - Value</span><div class="s"><span class="ay">Level 7 - Change</span><div class="az"><span class="a0">Level 8 - Delta</span></div></div></div></div></div></div></div><div class="af"><span class="ag">Level 3 - Form Card</span><div class="ah"><span class="l">Level 4 - Form Section</span><div class="g"><div class="a1"><span class="a2">Level 5 - Field Group</span><input class="a3" type="text" placeholder="Name"><div class="a4"><span class="a5">Level 6 - Validation Error</span><div class="s"><span class="a6">Level 7 - Error Detail</span><div class="a7"><span class="a8">Level 8 - Error Code</span></div></div></div></div><div class="a1"><span class="a2">Level 5 - Select Group</span><select class="a3"><option value="a">Option A</option><option value="b">Option B</option><option value="c">Option C</option></select></div></div></div></div><div class="af"><span class="ag">Level 3 - Nested Lists Card</span><div class="ah"><span class="l">Level 4 - Category Browser</span><div class="a9"><div class="ba"><span class="bb">Level 5 - Electronics</span><div class="j"><div class="bc"><div class="bd"><div class="be"></div><span class="bf">Level 6 - Subcategory</span></div><div class="s"><span class="bg">Level 7 - Item</span><div class="bh"><span class="r">Level 8 - Variant</span></div></div></div></div></div><div class="ba"><span class="bb">Level 5 - Clothing</span><div class="j"><div class="bc"><div class="bd"><div class="be"></div><span class="bf">Level 6 - Subcategory</span></div><div class="s"><span class="bg">Level 7 - Item</span><div class="bh"><span class="r">Level 8 - Variant</span></div></div></div></div></div><div class="ba"><span class="bb">Level 5 - Books</span><div class="j"><div class="bc"><div class="bd"><div class="be"></div><span class="bf">Level 6 - Subcategory</span></div><div class="s"><span class="bg">Level 7 - Item</span><div class="bh"><span class="r">Level 8 - Variant</span></div></div></div></div></div></div></div></div></div></div></div></div><div class="bi"><span class="bj">Level 1 - Settings Panel</span><div class="ae"><div class="bk"><span class="f">Level 2 - Account Settings</span><div class="g"><div class="bl"><span class="i">Level 3 - Profile Section</span><div class="bm"><span class="bn">Level 4 - Avatar Upload</span><div class="bo"><span class="bp">Level 5 - Initials</span><div class="bq"><span class="br">Level 6 - Edit Icon</span><div class="s"><span class="v">Level 7 - Tooltip</span><div class="bs"><span class="bt">Level 8 - Tooltip Arrow</span></div></div></div></div></div></div><div class="bl"><span class="i">Level 3 - Preferences</span><div class="a9"><div class="bu"><span class="bv">Level 4 - Language</span><div class="bw"><span class="a2">Level 5 - Current Value</span></div></div><div class="bu"><span class="bv">Level 4 - Timezone</span><div class="bw"><span class="a2">Level 5 - Current Value</span></div></div><div class="bu"><span class="bv">Level 4 - Currency</span><div class="bw"><span class="a2">Level 5 - Current Value</span></div></div></div></div></div></div><div class="bk"><span class="f">Level 2 - Notification Preferences</span><div class="a9"><div class="bx"><span class="by">Email Notifications</span><div class="bz"><div class="b0"></div></div></div><div class="bx"><span class="by">Push Notifications</span><div class="bz"><div class="b0"></div></div></div><div class="bx"><span class="by">SMS Notifications</span><div class="bz"><div class="b0"></div></div></div><div class="bx"><span class="by">Slack Notifications</span><div class="bz"><div class="b0"></div></div></div></div></div></div></div><div class="b1"><span class="b2">Level 1 - Monitoring</span><div class="d"><div class="b3"><span class="b4">Level 2 - API</span><div class="b5"><span class="y">Level 3 - Healthy</span><div class="s"><div class="z"><div class="b6"></div><div class="b7"></div><div class="b8"></div><div class="b6"></div></div><div class="s"><span class="b9">Level 4 - Uptime 99.9%</span><div class="s"><span class="ca">Level 5 - Response 42ms</span><div class="cb"><span class="cc">Level 6 - p99 120ms</span><div class="s"><span class="cd">Level 7 - Throughput 1.2k/s</span><div class="ce"><span class="cf">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="b3"><span class="b4">Level 2 - Database</span><div class="b5"><span class="y">Level 3 - Healthy</span><div class="s"><div class="z"><div class="b6"></div><div class="b7"></div><div class="b8"></div><div class="b6"></div></div><div class="s"><span class="b9">Level 4 - Uptime 99.9%</span><div class="s"><span class="ca">Level 5 - Response 42ms</span><div class="cb"><span class="cc">Level 6 - p99 120ms</span><div class="s"><span class="cd">Level 7 - Throughput 1.2k/s</span><div class="ce"><span class="cf">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="b3"><span class="b4">Level 2 - Cache</span><div class="b5"><span class="y">Level 3 - Healthy</span><div class="s"><div class="z"><div class="b6"></div><div class="b7"></div><div class="b8"></div><div class="b6"></div></div><div class="s"><span class="b9">Level 4 - Uptime 99.9%</span><div class="s"><span class="ca">Level 5 - Response 42ms</span><div class="cb"><span class="cc">Level 6 - p99 120ms</span><div class="s"><span class="cd">Level 7 - Throughput 1.2k/s</span><div class="ce"><span class="cf">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="b3"><span class="b4">Level 2 - Queue</span><div class="b5"><span class="y">Level 3 - Healthy</span><div class="s"><div class="z"><div class="b6"></div><div class="b7"></div><div class="b8"></div><div class="b6"></div></div><div class="s"><span class="b9">Level 4 - Uptime 99.9%</span><div class="s"><span class="ca">Level 5 - Response 42ms</span><div class="cb"><span class="cc">Level 6 - p99 120ms</span><div class="s"><span class="cd">Level 7 - Throughput 1.2k/s</span><div class="ce"><span class="cf">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div></div></div></div></body></html>
1+<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Deeply Nested Stress Test</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--border:#e2e8f0;--radius:8;}@layer htmlang{.a{display:flex;flex-direction:column;gap:20px;padding:24px;}.b{display:flex;flex-direction:column;background:#f0f9ff;border-radius:12px;padding:20px;border:1px solid #bae6fd;}.c{font-weight:bold;font-size:20px;color:#0369a1;}.d{display:flex;flex-direction:row;gap:16px;margin-top:16px;}.e{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);flex:1;min-width:0;}.f{font-weight:bold;font-size:16px;color:#1e293b;}.g{display:flex;flex-direction:column;gap:8px;margin-top:12px;}.h{display:flex;flex-direction:column;background:#f1f5f9;border-radius:6px;padding:12px;}.i{font-size:14px;color:#475569;}.j{display:flex;flex-direction:column;gap:4px;margin-top:8px;}.k{display:flex;flex-direction:column;padding:8px 12px;border-radius:4px;transition:all 0.15s;}.l{font-size:13px;color:#64748b;}.m{display:flex;flex-direction:row;gap:6px;margin-top:4px;align-items:center;}.n{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#10b981;}.o{display:flex;flex-direction:column;padding:4px 8px;background:#dbeafe;border-radius:4px;}.p{font-size:11px;color:#1d4ed8;}.q{flex-direction:column;display:inline-block;margin-left:4px;}.r{font-size:10px;color:var(--primary);}.s{display:flex;flex-direction:column;margin-top:2px;}.t{font-size:9px;color:#93c5fd;}.u{display:flex;flex-direction:column;padding:2px 4px;background:#eff6ff;border-radius:2px;margin-top:1px;}.v{font-size:8px;color:#bfdbfe;}.w{display:flex;flex-direction:column;padding:8px 12px;border-radius:4px;}.x{display:flex;flex-direction:column;margin-top:4px;padding:6px;background:#f0fdf4;border-radius:4px;}.y{font-size:12px;color:#166534;}.z{display:flex;flex-direction:row;gap:4px;margin-top:2px;}.aa{display:flex;flex-direction:column;padding:2px 6px;background:#bbf7d0;border-radius:2px;}.ab{font-size:10px;color:#15803d;}.ac{display:flex;flex-direction:column;padding:2px 6px;background:#fef3c7;border-radius:2px;}.ad{font-size:10px;color:#92400e;}.ae{display:flex;flex-direction:column;gap:12px;margin-top:12px;}.af,.bo{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.ag{font-weight:bold;font-size:16px;}.ah{display:flex;flex-direction:column;background:#f8fafc;border-radius:6px;padding:12px;margin-top:8px;}.ai{display:flex;flex-direction:row;gap:8px;margin-top:8px;}.aj{display:flex;flex-direction:column;flex:1;min-width:0;background:#eff6ff;border-radius:4px;padding:8px;}.ak{font-size:12px;color:#1d4ed8;font-weight:bold;}.al{display:flex;flex-direction:column;margin-top:4px;height:60px;background:#dbeafe;border-radius:4px;padding:8px;}.am{font-size:20px;font-weight:bold;color:#1e40af;}.an{display:flex;flex-direction:row;gap:2px;margin-top:2px;}.ao{display:flex;flex-direction:column;width:4px;height:12px;background:#93c5fd;border-radius:1px;}.ap{display:flex;flex-direction:column;width:4px;height:18px;background:#60a5fa;border-radius:1px;}.aq{display:flex;flex-direction:column;width:4px;height:8px;background:#93c5fd;border-radius:1px;}.ar{display:flex;flex-direction:column;width:4px;height:22px;background:var(--primary);border-radius:1px;}.as{display:flex;flex-direction:column;width:2px;height:2px;border-radius:50%;background:white;margin-top:1px;}.at{font-size:6px;color:white;}.au{display:flex;flex-direction:column;flex:1;min-width:0;background:#f0fdf4;border-radius:4px;padding:8px;}.av{font-size:12px;color:#166534;font-weight:bold;}.aw{display:flex;flex-direction:column;margin-top:4px;height:60px;background:#dcfce7;border-radius:4px;padding:8px;}.ax{font-size:20px;font-weight:bold;color:#166534;}.ay{font-size:10px;color:#16a34a;}.az{flex-direction:column;padding:1px 4px;background:#bbf7d0;border-radius:2px;display:inline-block;}.a0{font-size:8px;color:#15803d;}.a1{display:flex;flex-direction:column;gap:8px;margin-top:8px;}.a2,.bb{display:flex;flex-direction:column;padding:8px;border:1px solid var(--border);border-radius:4px;}.a3{font-size:12px;color:#64748b;margin-bottom:4px;}.a4{padding:6px 10px;border-radius:4px;border:1px solid var(--border);width:100%;}.a5{display:flex;flex-direction:column;margin-top:4px;padding:4px 8px;background:#fef2f2;border-radius:4px;}.a6{font-size:11px;color:#991b1b;}.a7{font-size:10px;color:#dc2626;}.a8{display:flex;flex-direction:column;margin-top:1px;padding:2px 4px;background:#fee2e2;border-radius:2px;}.a9{font-size:9px;color:#b91c1c;}.ba{display:flex;flex-direction:column;gap:6px;margin-top:8px;}.bc{font-size:14px;font-weight:bold;color:#1e293b;}.bd{display:flex;flex-direction:column;gap:4px;margin-top:6px;margin-left:12px;}.be{display:flex;flex-direction:column;padding:6px;background:#f8fafc;border-radius:4px;}.bf{display:flex;flex-direction:row;gap:8px;align-items:center;}.bg{display:flex;flex-direction:column;width:8px;height:8px;border-radius:2px;background:var(--primary);}.bh{font-size:12px;color:#475569;}.bi{display:flex;flex-direction:column;margin-top:4px;margin-left:16px;}.bj{font-size:11px;color:#94a3b8;}.bk{display:flex;flex-direction:column;margin-left:12px;margin-top:2px;padding:2px 6px;background:#eff6ff;border-radius:2px;}.bl{display:flex;flex-direction:column;background:#fefce8;border-radius:12px;padding:20px;border:1px solid #fde68a;margin-top:20px;}.bm{font-weight:bold;font-size:20px;color:#854d0e;}.bn{display:flex;flex-direction:column;gap:12px;margin-top:16px;}.bp{display:flex;flex-direction:column;background:#f8fafc;border-radius:6px;padding:12px;}.bq{display:flex;flex-direction:column;margin-top:8px;padding:10px;border:1px solid var(--border);border-radius:6px;}.br{font-size:13px;color:#1e293b;}.bs{flex-direction:column;margin-top:6px;width:80px;height:80px;border-radius:50%;background:var(--border);display:flex;align-items:center;justify-content:center;}.bt{font-size:24px;color:#94a3b8;font-weight:bold;}.bu{flex-direction:column;position:absolute;bottom:0;right:0;width:24px;height:24px;border-radius:50%;background:var(--primary);display:flex;align-items:center;justify-content:center;}.bv{font-size:10px;color:white;}.bw{display:flex;flex-direction:column;margin-top:1px;}.bx{display:flex;flex-direction:column;padding:1px 3px;background:#1e3a5f;border-radius:2px;margin-top:1px;}.by{font-size:7px;color:white;}.bz{display:flex;flex-direction:row;gap:8px;align-items:center;padding:6px 8px;border:1px solid var(--border);border-radius:4px;}.b0{font-size:13px;color:#1e293b;flex:1;min-width:0;}.b1{display:flex;flex-direction:column;padding:4px 12px;background:#f1f5f9;border-radius:4px;}.b2{font-size:12px;color:#64748b;}.b3{display:flex;flex-direction:column;gap:6px;margin-top:12px;}.b4{display:flex;flex-direction:row;gap:8px;align-items:center;padding:8px;border-bottom:1px solid var(--border);}.b5{font-size:14px;color:#1e293b;flex:1;min-width:0;}.b6{display:flex;flex-direction:column;width:36px;height:20px;border-radius:10px;background:var(--primary);padding:2px;}.b7{display:flex;flex-direction:column;width:16px;height:16px;border-radius:50%;background:white;margin-left:16px;}.b8{display:flex;flex-direction:column;background:#fdf2f8;border-radius:12px;padding:20px;border:1px solid #fbcfe8;margin-top:20px;}.b9{font-weight:bold;font-size:20px;color:#9d174d;}.ca{display:flex;flex-direction:column;background:white;border-radius:8px;padding:12px;border:1px solid var(--border);flex:1;min-width:0;}.cb{font-weight:bold;font-size:14px;color:#1e293b;}.cc{display:flex;flex-direction:column;margin-top:8px;background:#f0fdf4;border-radius:6px;padding:8px;}.cd{display:flex;flex-direction:column;margin-top:4px;}.ce{display:flex;flex-direction:row;gap:4px;}.cf{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#86efac;border-radius:2px;}.cg{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#4ade80;border-radius:2px;}.ch{display:flex;flex-direction:column;flex:1;min-width:0;height:4px;background:#22c55e;border-radius:2px;}.ci{font-size:11px;color:#16a34a;}.cj{font-size:10px;color:#22c55e;}.ck{display:flex;flex-direction:column;margin-top:2px;padding:2px 6px;background:#dcfce7;border-radius:2px;}.cl{font-size:9px;color:#15803d;}.cm{font-size:8px;color:#4ade80;}.cn{display:flex;flex-direction:column;padding:1px 3px;background:#bbf7d0;border-radius:1px;margin-top:1px;}.co{font-size:7px;color:#166534;}.k:hover,.w:hover{background:var(--border);}.bb:hover{background:#f8fafc;}@media(prefers-color-scheme:dark){.af{background:#1e293b;}.ah{background:#0f172a;}}}</style></head><body><div class="a"><div class="b"><span class="c">Level 1 - App Shell</span><div class="d"><div class="e"><span class="f">Level 2 - Sidebar</span><div class="g"><div class="h"><span class="i">Level 3 - Nav Group</span><div class="j"><div class="k"><span class="l">Level 4 - Nav Item</span><div class="m"><div class="n"></div><div class="o"><span class="p">Level 5 - Badge</span><div class="q"><span class="r">Level 6 - Badge Detail</span><div class="s"><span class="t">Level 7 - Sub Detail</span><div class="u"><span class="v">Level 8 - Deepest Badge</span></div></div></div></div></div></div><div class="w"><span class="l">Level 4 - Second Nav Item</span><div class="x"><span class="y">Level 5 - Status</span><div class="z"><div class="aa"><span class="ab">Level 6 - Online</span></div><div class="ac"><span class="ad">Level 6 - Away</span></div></div></div></div></div></div><div class="h"><span class="i">Level 3 - Second Group</span><div class="j"><div class="w"><span class="l">Settings</span></div><div class="w"><span class="l">Profile</span></div><div class="w"><span class="l">Security</span></div></div></div></div></div><div class="e"><span class="f">Level 2 - Main Content</span><div class="ae"><div class="af"><span class="ag">Level 3 - Dashboard Card</span><div class="ah"><span class="l">Level 4 - Chart Area</span><div class="ai"><div class="aj"><span class="ak">Level 5 - Metric A</span><div class="al"><span class="am">Level 6 - Value</span><div class="s"><span class="r">Level 7 - Trend</span><div class="an"><div class="ao"></div><div class="ap"></div><div class="aq"></div><div class="ar"><div class="as"><span class="at">Level 8 - Spark Dot</span></div></div></div></div></div></div><div class="au"><span class="av">Level 5 - Metric B</span><div class="aw"><span class="ax">Level 6 - Value</span><div class="s"><span class="ay">Level 7 - Change</span><div class="az"><span class="a0">Level 8 - Delta</span></div></div></div></div></div></div></div><div class="af"><span class="ag">Level 3 - Form Card</span><div class="ah"><span class="l">Level 4 - Form Section</span><div class="a1"><div class="a2"><span class="a3">Level 5 - Field Group</span><input class="a4" type="text" placeholder="Name"><div class="a5"><span class="a6">Level 6 - Validation Error</span><div class="s"><span class="a7">Level 7 - Error Detail</span><div class="a8"><span class="a9">Level 8 - Error Code</span></div></div></div></div><div class="a2"><span class="a3">Level 5 - Select Group</span><select class="a4"><option value="a">Option A</option><option value="b">Option B</option><option value="c">Option C</option></select></div></div></div></div><div class="af"><span class="ag">Level 3 - Nested Lists Card</span><div class="ah"><span class="l">Level 4 - Category Browser</span><div class="ba"><div class="bb"><span class="bc">Level 5 - Electronics</span><div class="bd"><div class="be"><div class="bf"><div class="bg"></div><span class="bh">Level 6 - Subcategory</span></div><div class="bi"><span class="bj">Level 7 - Item</span><div class="bk"><span class="r">Level 8 - Variant</span></div></div></div></div></div><div class="bb"><span class="bc">Level 5 - Clothing</span><div class="bd"><div class="be"><div class="bf"><div class="bg"></div><span class="bh">Level 6 - Subcategory</span></div><div class="bi"><span class="bj">Level 7 - Item</span><div class="bk"><span class="r">Level 8 - Variant</span></div></div></div></div></div><div class="bb"><span class="bc">Level 5 - Books</span><div class="bd"><div class="be"><div class="bf"><div class="bg"></div><span class="bh">Level 6 - Subcategory</span></div><div class="bi"><span class="bj">Level 7 - Item</span><div class="bk"><span class="r">Level 8 - Variant</span></div></div></div></div></div></div></div></div></div></div></div></div><div class="bl"><span class="bm">Level 1 - Settings Panel</span><div class="bn"><div class="bo"><span class="f">Level 2 - Account Settings</span><div class="g"><div class="bp"><span class="i">Level 3 - Profile Section</span><div class="bq"><span class="br">Level 4 - Avatar Upload</span><div class="bs"><span class="bt">Level 5 - Initials</span><div class="bu"><span class="bv">Level 6 - Edit Icon</span><div class="bw"><span class="v">Level 7 - Tooltip</span><div class="bx"><span class="by">Level 8 - Tooltip Arrow</span></div></div></div></div></div></div><div class="bp"><span class="i">Level 3 - Preferences</span><div class="ba"><div class="bz"><span class="b0">Level 4 - Language</span><div class="b1"><span class="b2">Level 5 - Current Value</span></div></div><div class="bz"><span class="b0">Level 4 - Timezone</span><div class="b1"><span class="b2">Level 5 - Current Value</span></div></div><div class="bz"><span class="b0">Level 4 - Currency</span><div class="b1"><span class="b2">Level 5 - Current Value</span></div></div></div></div></div></div><div class="bo"><span class="f">Level 2 - Notification Preferences</span><div class="b3"><div class="b4"><span class="b5">Email Notifications</span><div class="b6"><div class="b7"></div></div></div><div class="b4"><span class="b5">Push Notifications</span><div class="b6"><div class="b7"></div></div></div><div class="b4"><span class="b5">SMS Notifications</span><div class="b6"><div class="b7"></div></div></div><div class="b4"><span class="b5">Slack Notifications</span><div class="b6"><div class="b7"></div></div></div></div></div></div></div><div class="b8"><span class="b9">Level 1 - Monitoring</span><div class="d"><div class="ca"><span class="cb">Level 2 - API</span><div class="cc"><span class="y">Level 3 - Healthy</span><div class="cd"><div class="ce"><div class="cf"></div><div class="cg"></div><div class="ch"></div><div class="cf"></div></div><div class="cd"><span class="ci">Level 4 - Uptime 99.9%</span><div class="s"><span class="cj">Level 5 - Response 42ms</span><div class="ck"><span class="cl">Level 6 - p99 120ms</span><div class="bw"><span class="cm">Level 7 - Throughput 1.2k/s</span><div class="cn"><span class="co">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="ca"><span class="cb">Level 2 - Database</span><div class="cc"><span class="y">Level 3 - Healthy</span><div class="cd"><div class="ce"><div class="cf"></div><div class="cg"></div><div class="ch"></div><div class="cf"></div></div><div class="cd"><span class="ci">Level 4 - Uptime 99.9%</span><div class="s"><span class="cj">Level 5 - Response 42ms</span><div class="ck"><span class="cl">Level 6 - p99 120ms</span><div class="bw"><span class="cm">Level 7 - Throughput 1.2k/s</span><div class="cn"><span class="co">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="ca"><span class="cb">Level 2 - Cache</span><div class="cc"><span class="y">Level 3 - Healthy</span><div class="cd"><div class="ce"><div class="cf"></div><div class="cg"></div><div class="ch"></div><div class="cf"></div></div><div class="cd"><span class="ci">Level 4 - Uptime 99.9%</span><div class="s"><span class="cj">Level 5 - Response 42ms</span><div class="ck"><span class="cl">Level 6 - p99 120ms</span><div class="bw"><span class="cm">Level 7 - Throughput 1.2k/s</span><div class="cn"><span class="co">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div><div class="ca"><span class="cb">Level 2 - Queue</span><div class="cc"><span class="y">Level 3 - Healthy</span><div class="cd"><div class="ce"><div class="cf"></div><div class="cg"></div><div class="ch"></div><div class="cf"></div></div><div class="cd"><span class="ci">Level 4 - Uptime 99.9%</span><div class="s"><span class="cj">Level 5 - Response 42ms</span><div class="ck"><span class="cl">Level 6 - p99 120ms</span><div class="bw"><span class="cm">Level 7 - Throughput 1.2k/s</span><div class="cn"><span class="co">Level 8 - Peak 2.4k/s</span></div></div></div></div></div></div></div></div></div></div></div></body></html>
tests/snapshots/stress_large.html+1−1
@@ -1 +1 @@
1−<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Stress Test Large Document</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--secondary:#10b981;--accent:#f59e0b;--danger:#ef4444;--dark:#1e293b;--light:#f8fafc;--gray:#64748b;--border:#e2e8f0;--radius:8;--gap:16;--gap-sm:8;--gap-lg:24;--h0:none solid currentColor;}@layer htmlang{.a{display:flex;flex-direction:row;gap:0;min-height:100vh;}.b{display:flex;flex-direction:column;width:260px;background:white;border-right:1px solid var(--border);padding:16px;gap:8px;}.c{display:flex;flex-direction:row;gap:12px;padding:8px;align-items:center;}.d{flex-direction:column;width:36px;height:36px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-weight:bold;}.e{display:flex;flex-direction:column;gap:2px;}.f{font-weight:bold;font-size:16px;color:var(--dark);}.g{font-size:12px;color:var(--gray);}.h{display:flex;flex-direction:column;width:100%;height:1px;background:var(--border);margin:8px 0;}.i{display:flex;flex-direction:column;}.j{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;letter-spacing:1px;}.k{color:var(--primary);font-weight:bold;padding:8px 12px;background:#eff6ff;border-radius:6px;}.l{color:var(--gray);padding:8px 12px;border-radius:6px;transition:all 0.15s;}.m{display:flex;flex-direction:column;gap:4px;}.n{display:flex;flex-direction:row;gap:8px;align-items:center;}.o{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--secondary);}.p{font-size:13px;color:var(--gray);}.q{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--accent);}.r{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#cbd5e1;}.s{display:flex;flex-direction:column;padding:12px;background:#f1f5f9;border-radius:8px;}.t{flex-direction:column;width:28px;height:28px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-weight:bold;}.u{display:flex;flex-direction:column;gap:0;}.v{font-size:13px;font-weight:bold;color:var(--dark);}.w{font-size:11px;color:var(--gray);}.x{display:flex;flex-direction:column;flex:1;min-width:0;background:var(--light);}.y{display:flex;flex-direction:column;padding:12px 24px;background:white;border-bottom:1px solid var(--border);}.z{display:flex;flex-direction:row;gap:16px;align-items:center;}.aa{display:flex;flex-direction:row;gap:8px;}.ab{color:var(--gray);font-size:14px;}.ac{color:var(--border);font-size:14px;}.ad{color:var(--dark);font-size:14px;}.ae{font-weight:bold;font-size:22px;color:var(--dark);}.af{display:flex;flex-direction:column;flex:1;min-width:0;}.ag{display:flex;flex-direction:row;gap:12px;align-items:center;}.ah{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;transition:all 0.2s;}.ai{display:flex;flex-direction:column;position:relative;}.aj{padding:8px 16px;background:var(--primary);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;}.ak{display:flex;flex-direction:column;position:absolute;top:-2px;right:-2px;}.al{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--danger);}.am{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;}.an{display:flex;flex-direction:column;padding:24px;overflow-y:auto;}.ao{display:flex;flex-direction:column;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px 16px;}.ap{color:#1e40af;font-size:14px;}.aq{display:flex;flex-direction:row;gap:16px;}.ar{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.as{font-size:14px;color:var(--gray);}.at{font-weight:bold;font-size:28px;color:var(--dark);}.au{font-size:12px;color:var(--secondary);}.av{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);transition:all 0.2s;animation:fade-in 0.3s ease;}.aw{font-weight:bold;font-size:18px;color:var(--dark);}.ax{flex-direction:column;height:200px;background:var(--light);border-radius:6px;display:flex;align-items:flex-end;padding:16px;gap:8px;}.ay{display:flex;flex-direction:column;width:100%;height:40%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.az{display:flex;flex-direction:column;width:100%;height:65%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a0{display:flex;flex-direction:column;width:100%;height:45%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a1{display:flex;flex-direction:column;width:100%;height:80%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a2{display:flex;flex-direction:column;width:100%;height:55%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a3{display:flex;flex-direction:column;width:100%;height:70%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a4{display:flex;flex-direction:column;width:100%;height:90%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a5{display:flex;flex-direction:column;width:100%;height:60%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a6{display:flex;flex-direction:column;width:100%;height:75%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a7{display:flex;flex-direction:column;width:100%;height:85%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a8{display:flex;flex-direction:column;width:100%;height:50%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a9{display:flex;flex-direction:column;width:100%;height:95%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.ba{display:flex;flex-direction:column;gap:12px;}.bb{display:flex;flex-direction:row;gap:12px;align-items:center;padding:8px;border-radius:6px;}.bc{flex-direction:column;width:32px;height:32px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-weight:bold;}.bd{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;}.be{font-size:14px;font-weight:bold;color:var(--dark);}.bf{display:flex;flex-direction:column;flex:1;min-width:0;gap:16px;}.bg{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:1px solid var(--border);}.bh{display:flex;flex-direction:column;width:200px;}.bi{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;}.bj{display:flex;flex-direction:column;width:150px;}.bk{display:flex;flex-direction:column;width:120px;}.bl{display:flex;flex-direction:row;gap:0;padding:12px 16px;border-bottom:1px solid var(--border);}.bm{font-size:14px;}.bn{display:flex;flex-direction:row;gap:0;}.bo{font-size:13px;color:var(--dark);flex:1;min-width:0;}.bp{display:flex;flex-direction:column;width:100%;height:8px;background:var(--border);border-radius:4px;overflow:hidden;}.bq{display:flex;flex-direction:column;width:67%;height:100%;background:var(--primary);border-radius:4px;}.br{display:flex;flex-direction:column;gap:8px;}.bs{display:flex;flex-direction:row;gap:12px;padding:8px 12px;align-items:center;}.bt{flex-direction:column;width:24px;height:24px;border-radius:50%;background:#eff6ff;display:flex;align-items:center;justify-content:center;}.bu{font-size:10px;color:var(--primary);font-weight:bold;}.bv{font-size:14px;color:var(--dark);flex:1;min-width:0;}.bw{display:flex;flex-direction:column;width:340px;gap:16px;}.bx{padding:8px 16px;background:var(--secondary);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;}.by{padding:8px 16px;background:var(--accent);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;}.bz{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;}.b0{display:flex;flex-direction:row;gap:10px;align-items:center;padding:6px 8px;border-radius:6px;transition:all 0.15s;}.b1{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;}.b2{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--secondary);}.b3{display:flex;flex-direction:row;gap:0;flex-wrap:wrap;}.b4{flex-direction:column;display:inline-block;padding:4px 10px;background:#f1f5f9;color:var(--gray);border-radius:4px;margin:2px;}.b5{display:flex;flex-direction:row;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border);align-items:center;}.b6{display:flex;flex-direction:row;gap:0;align-items:center;}.b7{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:var(--primary);padding:2px;cursor:pointer;transition:all 0.2s;}.b8{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;transition:all 0.2s;}.b9{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:#cbd5e1;padding:2px;cursor:pointer;transition:all 0.2s;}.ca{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;}.cb{padding:6px 12px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);cursor:pointer;transition:all 0.15s;}.cc{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:2px solid var(--border);border-radius:6 6 0 0;}.cd{display:flex;flex-direction:column;width:60px;}.ce{display:flex;flex-direction:row;gap:0;padding:10px 16px;border-bottom:1px solid var(--border);cursor:pointer;transition:all 0.1s;}.cf{flex-direction:column;width:24px;height:24px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-weight:bold;}.cg{font-size:14px;color:var(--dark);}.ch{flex-direction:column;display:inline-block;padding:2px 8px;background:var(--secondary);color:white;border-radius:12px;}.ci{display:flex;flex-direction:row;gap:16px;padding:12px 16px;align-items:center;border-top:1px solid var(--border);}.cj{display:flex;flex-direction:row;gap:4px;}.ck{padding:6px 10px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);cursor:pointer;}.cl{padding:6px 10px;border-radius:4px;border:1px solid var(--primary);background:var(--primary);color:white;cursor:pointer;}.cm{display:flex;flex-direction:column;padding:24px 24px;background:white;border-top:1px solid var(--border);}.cn{display:flex;flex-direction:row;gap:24px;}.co{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;}.cp{font-weight:bold;font-size:14px;color:var(--dark);}.cq{color:var(--gray);font-size:13px;}.l:hover{color:var(--primary);background:#f1f5f9;}.ab:hover,.cq:hover{color:var(--primary);}.aj:hover,.am:hover,.bx:hover,.by:hover,.bz:hover{background:var(--dark);}.av:hover{box-shadow:0 4 12 rgba(0,0,0,0.1);}.ay:hover,.az:hover,.a0:hover,.a1:hover,.a2:hover,.a3:hover,.a4:hover,.a5:hover,.a6:hover,.a7:hover,.a8:hover,.a9:hover{background:#2563eb;}.bb:hover,.bl:hover,.ce:hover{background:var(--light);}.b0:hover{background:#f1f5f9;}.cb:hover{background:#f1f5f9;color:var(--dark);}.ah:focus{border:1px solid var(--primary);}@media(min-width:640px){.bw{flex:1;min-width:0;}}@media(prefers-color-scheme:dark){.b{background:#0f172a;border-right:1px solid var(--dark);}.f,.v,.ad,.ae,.at,.aw,.be,.bo,.bv,.cg,.cp{color:white;}.h,.bp{background:#334155;}.k,.bt{background:#1e3a5f;}.s,.cb,.ck{background:var(--dark);}.x,.ax,.bg,.cc{background:#0f172a;}.y{background:#0f172a;border-bottom:1px solid var(--dark);}.ah{border:1px solid #334155;background:var(--dark);color:white;}.ar,.av{background:var(--dark);border:1px solid #334155;}.bl,.b5,.ce{border-bottom:1px solid #334155;}.b4{background:#334155;color:#94a3b8;}.b9{background:#475569;}.cm{background:#0f172a;border-top:1px solid var(--dark);}}}@keyframes fade-in{from{opacity:0}to{opacity:1}}@keyframes slide-down{0%{transform:translateY(-10px);opacity:0}100%{transform:translateY(0);opacity:1}}</style></head><body><div class="a"><div class="b"><div class="c"><div class="d"><span>HL</span></div><div class="e"><span class="f">htmlang</span><span class="g">Dashboard v2.0</span></div></div><div class="h"></div><div class="i"><span class="j">Navigation</span><div class="e"><a href="/dashboard" class="k">Dashboard</a><a href="/analytics" class="l">Analytics</a><a href="/projects" class="l">Projects</a><a href="/team" class="l">Team</a><a href="/messages" class="l">Messages</a><a href="/calendar" class="l">Calendar</a><a href="/documents" class="l">Documents</a><a href="/settings" class="l">Settings</a></div></div><div class="i"><span class="j">Favorites</span><div class="e"><a href="/project/alpha" class="l">Project Alpha</a><a href="/project/beta" class="l">Project Beta</a><a href="/reports/q4" class="l">Q4 Reports</a></div></div><div class="i"><span class="j">Shortcuts</span><div class="m"><div class="n"><div class="o"></div><span class="p">Online (12)</span></div><div class="n"><div class="q"></div><span class="p">Away (3)</span></div><div class="n"><div class="r"></div><span class="p">Offline (5)</span></div></div></div><div class="s"><div class="n"><div class="t"><span>JD</span></div><div class="u"><span class="v">Jane Doe</span><span class="w">jane@example.com</span></div></div></div></div><div class="x"><header class="y"><div class="z"><div class="e"><div class="aa"><div class="aa"><a href="/" class="ab">Home</a><span class="ac">/</span></div><span class="ad">Dashboard</span></div><span class="ae">Dashboard Overview</span></div><div class="af"></div><div class="ag"><input class="ah" type="search" placeholder="Search..."><div class="ai"><button class="aj">Alerts</button><div class="ak"><div class="al"></div></div></div><button class="am">Settings</button></div></div></header><div class="an"><div class="ao"><span class="ap">Welcome back! You have 3 new notifications and 2 pending tasks.</span></div><div class="aq"><div class="ar"><span class="as">Total Revenue</span><span class="at">$48</span><span class="au">+12.5% from last month</span></div><div class="ar"><span class="as">Active Users</span><span class="at">2</span><span class="au">+8.2% from last week</span></div><div class="ar"><span class="as">Conversion Rate</span><span class="at">3.24%</span><span class="au">+0.4% from yesterday</span></div><div class="ar"><span class="as">Open Tickets</span><span class="at">142</span><span class="au">-5.1% from last month</span></div></div><div class="aq"><div class="av"><span class="aw">Revenue Overview</span><div class="i"><div class="ax"><div class="ay"></div><div class="az"></div><div class="a0"></div><div class="a1"></div><div class="a2"></div><div class="a3"></div><div class="a4"></div><div class="a5"></div><div class="a6"></div><div class="a7"></div><div class="a8"></div><div class="a9"></div></div></div></div><div class="av"><span class="aw">Activity Feed</span><div class="i"><div class="ba"><div class="bb"><div class="bc"><span>Alice</span></div><div class="bd"><span class="be">Alice</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Bob</span></div><div class="bd"><span class="be">Bob</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Carol</span></div><div class="bd"><span class="be">Carol</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Dave</span></div><div class="bd"><span class="be">Dave</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Eve</span></div><div class="bd"><span class="be">Eve</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Frank</span></div><div class="bd"><span class="be">Frank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Grace</span></div><div class="bd"><span class="be">Grace</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bb"><div class="bc"><span>Hank</span></div><div class="bd"><span class="be">Hank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div></div></div></div></div><div class="aq"><div class="bf"><div class="av"><span class="aw">Project Status</span><div class="i"><div class="u"><div class="bg"><div class="bh"><span class="bi">Project</span></div><div class="bj"><span class="bi">Status</span></div><div class="bk"><span class="bi">Progress</span></div><div class="af"><span class="bi">Due Date</span></div></div><div class="bl"><div class="bh"><span class="bm">Project Alpha</span></div><div class="bj"><span class="as">In Progress</span></div><div class="bk"><span class="bm">75%</span></div><div class="af"><span class="as">Dec 15 2025</span></div></div><div class="bl"><div class="bh"><span class="bm">Project Beta</span></div><div class="bj"><span class="as">Review</span></div><div class="bk"><span class="bm">90%</span></div><div class="af"><span class="as">Nov 30 2025</span></div></div><div class="bl"><div class="bh"><span class="bm">Project Gamma</span></div><div class="bj"><span class="as">Planning</span></div><div class="bk"><span class="bm">20%</span></div><div class="af"><span class="as">Jan 20 2026</span></div></div><div class="bl"><div class="bh"><span class="bm">Project Delta</span></div><div class="bj"><span class="as">Completed</span></div><div class="bk"><span class="bm">100%</span></div><div class="af"><span class="as">Oct 10 2025</span></div></div><div class="bl"><div class="bh"><span class="bm">Project Epsilon</span></div><div class="bj"><span class="as">On Hold</span></div><div class="bk"><span class="bm">45%</span></div><div class="af"><span class="as">Feb 28 2026</span></div></div></div></div></div><div class="av"><span class="aw">Progress Breakdown</span><div class="i"><div class="ba"><div class="m"><div class="bn"><span class="bo">Alpha</span><span class="p">67%</span></div><div class="bp"><div class="bq"></div></div></div><div class="m"><div class="bn"><span class="bo">Beta</span><span class="p">67%</span></div><div class="bp"><div class="bq"></div></div></div><div class="m"><div class="bn"><span class="bo">Gamma</span><span class="p">67%</span></div><div class="bp"><div class="bq"></div></div></div><div class="m"><div class="bn"><span class="bo">Delta</span><span class="p">67%</span></div><div class="bp"><div class="bq"></div></div></div><div class="m"><div class="bn"><span class="bo">Epsilon</span><span class="p">67%</span></div><div class="bp"><div class="bq"></div></div></div></div></div></div><div class="av"><span class="aw">Recent Activity Log</span><div class="i"><div class="br"><div class="bs"><div class="bt"><span class="bu">v2.3.1 to production</span></div><span class="bv">Deployed</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">feature/auth-redesign</span></div><span class="bv">Merged</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">issue #482: Login timeout</span></div><span class="bv">Closed</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">CI/CD pipeline config</span></div><span class="bv">Updated</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">unit tests for payment module</span></div><span class="bv">Added</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">PR #156: API refactor</span></div><span class="bv">Reviewed</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">memory leak in worker pool</span></div><span class="bv">Fixed</span><span class="w">just now</span></div><div class="bs"><div class="bt"><span class="bu">hotfix 2.3.2</span></div><span class="bv">Released</span><span class="w">just now</span></div></div></div></div></div><div class="bw"><div class="av"><span class="aw">Quick Actions</span><div class="i"><div class="br"><button class="aj">New Project</button><button class="bx">Create Report</button><button class="by">Invite Member</button><button class="bz">View Backlog</button></div></div></div><div class="av"><span class="aw">Team Members</span><div class="i"><div class="br"><div class="b0"><div class="t"><span>Alice</span></div><div class="b1"><span class="v">Alice</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Bob</span></div><div class="b1"><span class="v">Bob</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Carol</span></div><div class="b1"><span class="v">Carol</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Dave</span></div><div class="b1"><span class="v">Dave</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Eve</span></div><div class="b1"><span class="v">Eve</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Frank</span></div><div class="b1"><span class="v">Frank</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Grace</span></div><div class="b1"><span class="v">Grace</span><span class="w">Developer</span></div><div class="b2"></div></div><div class="b0"><div class="t"><span>Hank</span></div><div class="b1"><span class="v">Hank</span><span class="w">Developer</span></div><div class="b2"></div></div></div></div></div><div class="av"><span class="aw">Tags</span><div class="i"><div class="b3"><div class="b4"><span>frontend</span></div><div class="b4"><span>backend</span></div><div class="b4"><span>devops</span></div><div class="b4"><span>design</span></div><div class="b4"><span>mobile</span></div><div class="b4"><span>security</span></div><div class="b4"><span>performance</span></div><div class="b4"><span>testing</span></div><div class="b4"><span>docs</span></div><div class="b4"><span>infra</span></div><div class="b4"><span>ux</span></div><div class="b4"><span>api</span></div></div></div></div><div class="av"><span class="aw">Notifications</span><div class="i"><div class="u"><div class="b5"><div class="al"></div><span class="bo">New deployment completed</span><span class="w">now</span></div><div class="b5"><div class="al"></div><span class="bo">PR review requested</span><span class="w">now</span></div><div class="b5"><div class="al"></div><span class="bo">Build failed on staging</span><span class="w">now</span></div><div class="b5"><div class="al"></div><span class="bo">Meeting in 30 minutes</span><span class="w">now</span></div><div class="b5"><div class="al"></div><span class="bo">Subscription renewal due</span><span class="w">now</span></div></div></div></div><div class="av"><span class="aw">Settings</span><div class="i"><div class="ba"><div class="b6"><span class="bv">Dark Mode</span><div class="b7"><div class="b8"></div></div></div><div class="b6"><span class="bv">Notifications</span><div class="b7"><div class="b8"></div></div></div><div class="b6"><span class="bv">Auto-save</span><div class="b9"><div class="b8"></div></div></div><div class="b6"><span class="bv">Compact View</span><div class="b9"><div class="b8"></div></div></div></div></div></div></div></div><div class="i"><div class="av"><span class="aw">Data Table</span><div class="i"><div class="u"><div class="z"><input class="ca" type="search" placeholder="Filter results..."><div class="af"></div><div class="aa"><button class="cb">all</button><button class="cb">design</button><button class="cb">development</button><button class="cb">marketing</button><button class="cb">analytics</button></div></div><div class="cc"><div class="cd"><span class="bi">ID</span></div><div class="bh"><span class="bi">Name</span></div><div class="bj"><span class="bi">Category</span></div><div class="bk"><span class="bi">Status</span></div><div class="af"><span class="bi">Updated</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Alpha</span></div><span class="cg">Alpha</span></div></div><div class="bj"><span class="p">active</span></div><div class="bk"><div class="ch"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Beta</span></div><span class="cg">Beta</span></div></div><div class="bj"><span class="p">active</span></div><div class="bk"><div class="ch"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Gamma</span></div><span class="cg">Gamma</span></div></div><div class="bj"><span class="p">active</span></div><div class="bk"><div class="ch"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Delta</span></div><span class="cg">Delta</span></div></div><div class="bj"><span class="p">active</span></div><div class="bk"><div class="ch"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Epsilon</span></div><span class="cg">Epsilon</span></div></div><div class="bj"><span class="p">active</span></div><div class="bk"><div class="ch"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Alpha</span></div><span class="cg">Alpha</span></div></div><div class="bj"><span class="p">pending</span></div><div class="bk"><div class="ch"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Beta</span></div><span class="cg">Beta</span></div></div><div class="bj"><span class="p">pending</span></div><div class="bk"><div class="ch"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Gamma</span></div><span class="cg">Gamma</span></div></div><div class="bj"><span class="p">pending</span></div><div class="bk"><div class="ch"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Delta</span></div><span class="cg">Delta</span></div></div><div class="bj"><span class="p">pending</span></div><div class="bk"><div class="ch"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Epsilon</span></div><span class="cg">Epsilon</span></div></div><div class="bj"><span class="p">pending</span></div><div class="bk"><div class="ch"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Alpha</span></div><span class="cg">Alpha</span></div></div><div class="bj"><span class="p">completed</span></div><div class="bk"><div class="ch"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Beta</span></div><span class="cg">Beta</span></div></div><div class="bj"><span class="p">completed</span></div><div class="bk"><div class="ch"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Gamma</span></div><span class="cg">Gamma</span></div></div><div class="bj"><span class="p">completed</span></div><div class="bk"><div class="ch"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Delta</span></div><span class="cg">Delta</span></div></div><div class="bj"><span class="p">completed</span></div><div class="bk"><div class="ch"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Epsilon</span></div><span class="cg">Epsilon</span></div></div><div class="bj"><span class="p">completed</span></div><div class="bk"><div class="ch"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Alpha</span></div><span class="cg">Alpha</span></div></div><div class="bj"><span class="p">archived</span></div><div class="bk"><div class="ch"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Beta</span></div><span class="cg">Beta</span></div></div><div class="bj"><span class="p">archived</span></div><div class="bk"><div class="ch"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Gamma</span></div><span class="cg">Gamma</span></div></div><div class="bj"><span class="p">archived</span></div><div class="bk"><div class="ch"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Delta</span></div><span class="cg">Delta</span></div></div><div class="bj"><span class="p">archived</span></div><div class="bk"><div class="ch"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ce"><div class="cd"><span class="p">#42</span></div><div class="bh"><div class="n"><div class="cf"><span>Epsilon</span></div><span class="cg">Epsilon</span></div></div><div class="bj"><span class="p">archived</span></div><div class="bk"><div class="ch"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ci"><span class="p">Showing 1-20 of 142 results</span><div class="af"></div><div class="cj"><button class="ck">Prev</button><button class="cl">1</button><button class="ck">2</button><button class="ck">3</button><button class="ck">Next</button></div></div></div></div></div></div></div><footer class="cm"><div class="cn"><div class="co"><span class="cp">htmlang Dashboard</span><span class="g">Built with htmlang - a declarative HTML language</span><span class="w">Copyright 2025 htmlang contributors</span></div><div class="m"><span class="bi">Product</span><a href="/features" class="cq">Features</a><a href="/pricing" class="cq">Pricing</a><a href="/changelog" class="cq">Changelog</a><a href="/roadmap" class="cq">Roadmap</a></div><div class="m"><span class="bi">Resources</span><a href="/docs" class="cq">Documentation</a><a href="/api" class="cq">API Reference</a><a href="/guides" class="cq">Guides</a><a href="/examples" class="cq">Examples</a></div><div class="m"><span class="bi">Company</span><a href="/about" class="cq">About</a><a href="/blog" class="cq">Blog</a><a href="/careers" class="cq">Careers</a><a href="/contact" class="cq">Contact</a></div><div class="m"><span class="bi">Legal</span><a href="/privacy" class="cq">Privacy Policy</a><a href="/terms" class="cq">Terms of Service</a><a href="/cookies" class="cq">Cookie Policy</a></div></div></footer></div></div></body></html>
1+<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Stress Test Large Document</title><style>@layer hl-reset,htmlang;@layer hl-reset{*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif}img{display:block}a{text-decoration:none;color:inherit}a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid currentColor;outline-offset:2px}}:root{--primary:#3b82f6;--secondary:#10b981;--accent:#f59e0b;--danger:#ef4444;--dark:#1e293b;--light:#f8fafc;--gray:#64748b;--border:#e2e8f0;--radius:8;--gap:16;--gap-sm:8;--gap-lg:24;--h0:none solid currentColor;}@layer htmlang{.a{display:flex;flex-direction:row;gap:0;min-height:100vh;}.b{display:flex;flex-direction:column;width:260px;background:white;border-right:1px solid var(--border);padding:16px;gap:8px;}.c{display:flex;flex-direction:row;gap:12px;padding:8px;align-items:center;}.d{flex-direction:column;width:36px;height:36px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.e{display:flex;flex-direction:column;gap:2px;}.f{font-weight:bold;font-size:16px;color:var(--dark);}.g{font-size:12px;color:var(--gray);}.h{display:flex;flex-direction:column;width:100%;height:1px;background:var(--border);margin:8px 0;}.i{display:flex;flex-direction:column;margin-bottom:24px;}.j{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;letter-spacing:1px;margin-bottom:8px;}.k{color:var(--primary);font-weight:bold;padding:8px 12px;background:#eff6ff;border-radius:6px;}.l{color:var(--gray);padding:8px 12px;border-radius:6px;transition:all 0.15s;}.m{display:flex;flex-direction:column;gap:4px;}.n{display:flex;flex-direction:row;gap:8px;align-items:center;}.o{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--secondary);}.p{font-size:13px;color:var(--gray);}.q{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:var(--accent);}.r{display:flex;flex-direction:column;width:6px;height:6px;border-radius:50%;background:#cbd5e1;}.s{display:flex;flex-direction:column;margin-top:auto;padding:12px;background:#f1f5f9;border-radius:8px;}.t{flex-direction:column;width:28px;height:28px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.u{display:flex;flex-direction:column;gap:0;}.v{font-size:13px;font-weight:bold;color:var(--dark);}.w{font-size:11px;color:var(--gray);}.x{display:flex;flex-direction:column;flex:1;min-width:0;background:var(--light);}.y{display:flex;flex-direction:column;padding:12px 24px;background:white;border-bottom:1px solid var(--border);}.z{display:flex;flex-direction:row;gap:16px;align-items:center;}.aa{display:flex;flex-direction:row;gap:8px;}.ab{color:var(--gray);font-size:14px;}.ac{color:var(--border);font-size:14px;}.ad{color:var(--dark);font-size:14px;}.ae{font-weight:bold;font-size:22px;color:var(--dark);}.af{display:flex;flex-direction:column;flex:1;min-width:0;}.ag{display:flex;flex-direction:row;gap:12px;align-items:center;}.ah{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;transition:all 0.2s;}.ai{display:flex;flex-direction:column;position:relative;}.aj{padding:8px 16px;background:var(--primary);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;font-size:14px;}.ak{display:flex;flex-direction:column;position:absolute;top:-2px;right:-2px;}.al{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--danger);}.am{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;font-size:14px;}.an{display:flex;flex-direction:column;padding:24px;overflow-y:auto;}.ao{display:flex;flex-direction:column;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;padding:12px 16px;}.ap{color:#1e40af;font-size:14px;}.aq,.av{display:flex;flex-direction:row;gap:16px;margin-top:24px;}.ar{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);}.as{font-size:14px;color:var(--gray);}.at{font-weight:bold;font-size:28px;color:var(--dark);margin-top:4px;}.au{font-size:12px;color:var(--secondary);margin-top:2px;}.aw{display:flex;flex-direction:column;background:white;border-radius:8px;padding:16px;border:1px solid var(--border);transition:all 0.2s;animation:fade-in 0.3s ease;}.ax{font-weight:bold;font-size:18px;color:var(--dark);}.ay{display:flex;flex-direction:column;margin-top:8px;}.az{flex-direction:column;height:200px;background:var(--light);border-radius:6px;margin-top:12px;display:flex;align-items:flex-end;padding:16px;gap:8px;}.a0{display:flex;flex-direction:column;width:100%;height:40%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a1{display:flex;flex-direction:column;width:100%;height:65%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a2{display:flex;flex-direction:column;width:100%;height:45%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a3{display:flex;flex-direction:column;width:100%;height:80%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a4{display:flex;flex-direction:column;width:100%;height:55%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a5{display:flex;flex-direction:column;width:100%;height:70%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a6{display:flex;flex-direction:column;width:100%;height:90%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a7{display:flex;flex-direction:column;width:100%;height:60%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a8{display:flex;flex-direction:column;width:100%;height:75%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.a9{display:flex;flex-direction:column;width:100%;height:85%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.ba{display:flex;flex-direction:column;width:100%;height:50%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.bb{display:flex;flex-direction:column;width:100%;height:95%;background:var(--primary);border-radius:4 4 0 0;transition:all 0.2s;min-width:20px;}.bc{display:flex;flex-direction:column;gap:12px;margin-top:12px;}.bd{display:flex;flex-direction:row;gap:12px;align-items:center;padding:8px;border-radius:6px;}.be{flex-direction:column;width:32px;height:32px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.bf{display:flex;flex-direction:column;gap:2px;flex:1;min-width:0;}.bg{font-size:14px;font-weight:bold;color:var(--dark);}.bh{display:flex;flex-direction:column;flex:1;min-width:0;gap:16px;}.bi{display:flex;flex-direction:column;gap:0;margin-top:12px;}.bj{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:1px solid var(--border);}.bk{display:flex;flex-direction:column;width:200px;}.bl{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;}.bm{display:flex;flex-direction:column;width:150px;}.bn{display:flex;flex-direction:column;width:120px;}.bo{display:flex;flex-direction:row;gap:0;padding:12px 16px;border-bottom:1px solid var(--border);}.bp{font-size:14px;}.bq{display:flex;flex-direction:row;gap:0;}.br{font-size:13px;color:var(--dark);flex:1;min-width:0;}.bs{display:flex;flex-direction:column;width:100%;height:8px;background:var(--border);border-radius:4px;overflow:hidden;}.bt{display:flex;flex-direction:column;width:67%;height:100%;background:var(--primary);border-radius:4px;}.bu{display:flex;flex-direction:column;gap:8px;margin-top:12px;}.bv{display:flex;flex-direction:row;gap:12px;padding:8px 12px;align-items:center;}.bw{flex-direction:column;width:24px;height:24px;border-radius:50%;background:#eff6ff;display:flex;align-items:center;justify-content:center;}.bx{font-size:10px;color:var(--primary);font-weight:bold;}.by{font-size:14px;color:var(--dark);flex:1;min-width:0;}.bz{display:flex;flex-direction:column;width:340px;gap:16px;}.b0{padding:8px 16px;background:var(--secondary);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;font-size:14px;}.b1{padding:8px 16px;background:var(--accent);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;font-size:14px;}.b2{padding:8px 16px;background:var(--gray);color:white;border-radius:6px;border:var(--h0);cursor:pointer;transition:all 0.2s;font-size:14px;}.b3{display:flex;flex-direction:row;gap:10px;align-items:center;padding:6px 8px;border-radius:6px;transition:all 0.15s;}.b4{display:flex;flex-direction:column;gap:0;flex:1;min-width:0;}.b5{display:flex;flex-direction:column;width:8px;height:8px;border-radius:50%;background:var(--secondary);}.b6{display:flex;flex-direction:row;gap:0;flex-wrap:wrap;margin-top:8px;}.b7{flex-direction:column;display:inline-block;padding:4px 10px;background:#f1f5f9;color:var(--gray);border-radius:4px;font-size:12px;margin:2px;}.b8{display:flex;flex-direction:row;gap:10px;padding:10px 12px;border-bottom:1px solid var(--border);align-items:center;}.b9{display:flex;flex-direction:row;gap:0;align-items:center;}.ca{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:var(--primary);padding:2px;cursor:pointer;transition:all 0.2s;}.cb{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;margin-left:18px;transition:all 0.2s;}.cc{display:flex;flex-direction:column;width:40px;height:22px;border-radius:11px;background:#cbd5e1;padding:2px;cursor:pointer;transition:all 0.2s;}.cd{display:flex;flex-direction:column;width:18px;height:18px;border-radius:50%;background:white;transition:all 0.2s;}.ce{display:flex;flex-direction:column;margin-top:24px;}.cf{display:flex;flex-direction:row;gap:16px;margin-bottom:12px;align-items:center;}.cg{padding:8px 12px;border-radius:6px;border:1px solid var(--border);width:240px;}.ch{padding:6px 12px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;transition:all 0.15s;}.ci{display:flex;flex-direction:row;gap:0;padding:8px 16px;background:var(--light);border-bottom:2px solid var(--border);border-radius:6 6 0 0;}.cj{display:flex;flex-direction:column;width:60px;}.ck{display:flex;flex-direction:row;gap:0;padding:10px 16px;border-bottom:1px solid var(--border);cursor:pointer;transition:all 0.1s;}.cl{flex-direction:column;width:24px;height:24px;border-radius:50%;background:var(--primary);color:white;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;}.cm{font-size:14px;color:var(--dark);}.cn{flex-direction:column;display:inline-block;padding:2px 8px;background:var(--secondary);color:white;border-radius:12px;font-size:12px;}.co{display:flex;flex-direction:row;gap:16px;padding:12px 16px;align-items:center;border-top:1px solid var(--border);}.cp{display:flex;flex-direction:row;gap:4px;}.cq{padding:6px 10px;border-radius:4px;border:1px solid var(--border);background:white;color:var(--gray);font-size:13px;cursor:pointer;}.cr{padding:6px 10px;border-radius:4px;border:1px solid var(--primary);background:var(--primary);color:white;font-size:13px;cursor:pointer;}.cs{display:flex;flex-direction:column;padding:24px 24px;background:white;border-top:1px solid var(--border);}.ct{display:flex;flex-direction:row;gap:24px;}.cu{display:flex;flex-direction:column;gap:8px;flex:1;min-width:0;}.cv{font-weight:bold;font-size:14px;color:var(--dark);}.cw{font-weight:bold;font-size:12px;color:var(--gray);text-transform:uppercase;margin-bottom:4px;}.cx{color:var(--gray);font-size:13px;}.l:hover{color:var(--primary);background:#f1f5f9;}.ab:hover,.cx:hover{color:var(--primary);}.aj:hover,.am:hover,.b0:hover,.b1:hover,.b2:hover{background:var(--dark);}.aw:hover{box-shadow:0 4 12 rgba(0,0,0,0.1);}.a0:hover,.a1:hover,.a2:hover,.a3:hover,.a4:hover,.a5:hover,.a6:hover,.a7:hover,.a8:hover,.a9:hover,.ba:hover,.bb:hover{background:#2563eb;}.bd:hover,.bo:hover,.ck:hover{background:var(--light);}.b3:hover{background:#f1f5f9;}.ch:hover{background:#f1f5f9;color:var(--dark);}.ah:focus{border:1px solid var(--primary);}@media(min-width:640px){.aq,.ct{flex-direction:column;}.bz{flex:1;min-width:0;}}@media(min-width:1024px){.aq,.ct{flex-direction:row;}}@media(prefers-color-scheme:dark){.b{background:#0f172a;border-right:1px solid var(--dark);}.f,.v,.ad,.ae,.at,.ax,.bg,.br,.by,.cm,.cv{color:white;}.h,.bs{background:#334155;}.k,.bw{background:#1e3a5f;}.s,.ch,.cq{background:var(--dark);}.x,.az,.bj,.ci{background:#0f172a;}.y{background:#0f172a;border-bottom:1px solid var(--dark);}.ah{border:1px solid #334155;background:var(--dark);color:white;}.ar,.aw{background:var(--dark);border:1px solid #334155;}.bo,.b8,.ck{border-bottom:1px solid #334155;}.b7{background:#334155;color:#94a3b8;}.cc{background:#475569;}.cs{background:#0f172a;border-top:1px solid var(--dark);}}}@keyframes fade-in{from{opacity:0}to{opacity:1}}@keyframes slide-down{0%{transform:translateY(-10px);opacity:0}100%{transform:translateY(0);opacity:1}}</style></head><body><div class="a"><div class="b"><div class="c"><div class="d"><span>HL</span></div><div class="e"><span class="f">htmlang</span><span class="g">Dashboard v2.0</span></div></div><div class="h"></div><div class="i"><span class="j">Navigation</span><div class="e"><a href="/dashboard" class="k">Dashboard</a><a href="/analytics" class="l">Analytics</a><a href="/projects" class="l">Projects</a><a href="/team" class="l">Team</a><a href="/messages" class="l">Messages</a><a href="/calendar" class="l">Calendar</a><a href="/documents" class="l">Documents</a><a href="/settings" class="l">Settings</a></div></div><div class="i"><span class="j">Favorites</span><div class="e"><a href="/project/alpha" class="l">Project Alpha</a><a href="/project/beta" class="l">Project Beta</a><a href="/reports/q4" class="l">Q4 Reports</a></div></div><div class="i"><span class="j">Shortcuts</span><div class="m"><div class="n"><div class="o"></div><span class="p">Online (12)</span></div><div class="n"><div class="q"></div><span class="p">Away (3)</span></div><div class="n"><div class="r"></div><span class="p">Offline (5)</span></div></div></div><div class="s"><div class="n"><div class="t"><span>JD</span></div><div class="u"><span class="v">Jane Doe</span><span class="w">jane@example.com</span></div></div></div></div><div class="x"><header class="y"><div class="z"><div class="e"><div class="aa"><div class="aa"><a href="/" class="ab">Home</a><span class="ac">/</span></div><span class="ad">Dashboard</span></div><span class="ae">Dashboard Overview</span></div><div class="af"></div><div class="ag"><input class="ah" type="search" placeholder="Search..."><div class="ai"><button class="aj">Alerts</button><div class="ak"><div class="al"></div></div></div><button class="am">Settings</button></div></div></header><div class="an"><div class="ao"><span class="ap">Welcome back! You have 3 new notifications and 2 pending tasks.</span></div><div class="aq"><div class="ar"><span class="as">Total Revenue</span><span class="at">$48</span><span class="au">+12.5% from last month</span></div><div class="ar"><span class="as">Active Users</span><span class="at">2</span><span class="au">+8.2% from last week</span></div><div class="ar"><span class="as">Conversion Rate</span><span class="at">3.24%</span><span class="au">+0.4% from yesterday</span></div><div class="ar"><span class="as">Open Tickets</span><span class="at">142</span><span class="au">-5.1% from last month</span></div></div><div class="av"><div class="aw"><span class="ax">Revenue Overview</span><div class="ay"><div class="az"><div class="a0"></div><div class="a1"></div><div class="a2"></div><div class="a3"></div><div class="a4"></div><div class="a5"></div><div class="a6"></div><div class="a7"></div><div class="a8"></div><div class="a9"></div><div class="ba"></div><div class="bb"></div></div></div></div><div class="aw"><span class="ax">Activity Feed</span><div class="ay"><div class="bc"><div class="bd"><div class="be"><span>Alice</span></div><div class="bf"><span class="bg">Alice</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Bob</span></div><div class="bf"><span class="bg">Bob</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Carol</span></div><div class="bf"><span class="bg">Carol</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Dave</span></div><div class="bf"><span class="bg">Dave</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Eve</span></div><div class="bf"><span class="bg">Eve</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Frank</span></div><div class="bf"><span class="bg">Frank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Grace</span></div><div class="bf"><span class="bg">Grace</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div><div class="bd"><div class="be"><span>Hank</span></div><div class="bf"><span class="bg">Hank</span><span class="g">Updated project files</span></div><span class="w">2h ago</span></div></div></div></div></div><div class="aq"><div class="bh"><div class="aw"><span class="ax">Project Status</span><div class="ay"><div class="bi"><div class="bj"><div class="bk"><span class="bl">Project</span></div><div class="bm"><span class="bl">Status</span></div><div class="bn"><span class="bl">Progress</span></div><div class="af"><span class="bl">Due Date</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Alpha</span></div><div class="bm"><span class="as">In Progress</span></div><div class="bn"><span class="bp">75%</span></div><div class="af"><span class="as">Dec 15 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Beta</span></div><div class="bm"><span class="as">Review</span></div><div class="bn"><span class="bp">90%</span></div><div class="af"><span class="as">Nov 30 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Gamma</span></div><div class="bm"><span class="as">Planning</span></div><div class="bn"><span class="bp">20%</span></div><div class="af"><span class="as">Jan 20 2026</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Delta</span></div><div class="bm"><span class="as">Completed</span></div><div class="bn"><span class="bp">100%</span></div><div class="af"><span class="as">Oct 10 2025</span></div></div><div class="bo"><div class="bk"><span class="bp">Project Epsilon</span></div><div class="bm"><span class="as">On Hold</span></div><div class="bn"><span class="bp">45%</span></div><div class="af"><span class="as">Feb 28 2026</span></div></div></div></div></div><div class="aw"><span class="ax">Progress Breakdown</span><div class="ay"><div class="bc"><div class="m"><div class="bq"><span class="br">Alpha</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Beta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Gamma</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Delta</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div><div class="m"><div class="bq"><span class="br">Epsilon</span><span class="p">67%</span></div><div class="bs"><div class="bt"></div></div></div></div></div></div><div class="aw"><span class="ax">Recent Activity Log</span><div class="ay"><div class="bu"><div class="bv"><div class="bw"><span class="bx">v2.3.1 to production</span></div><span class="by">Deployed</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">feature/auth-redesign</span></div><span class="by">Merged</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">issue #482: Login timeout</span></div><span class="by">Closed</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">CI/CD pipeline config</span></div><span class="by">Updated</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">unit tests for payment module</span></div><span class="by">Added</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">PR #156: API refactor</span></div><span class="by">Reviewed</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">memory leak in worker pool</span></div><span class="by">Fixed</span><span class="w">just now</span></div><div class="bv"><div class="bw"><span class="bx">hotfix 2.3.2</span></div><span class="by">Released</span><span class="w">just now</span></div></div></div></div></div><div class="bz"><div class="aw"><span class="ax">Quick Actions</span><div class="ay"><div class="bu"><button class="aj">New Project</button><button class="b0">Create Report</button><button class="b1">Invite Member</button><button class="b2">View Backlog</button></div></div></div><div class="aw"><span class="ax">Team Members</span><div class="ay"><div class="bu"><div class="b3"><div class="t"><span>Alice</span></div><div class="b4"><span class="v">Alice</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Bob</span></div><div class="b4"><span class="v">Bob</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Carol</span></div><div class="b4"><span class="v">Carol</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Dave</span></div><div class="b4"><span class="v">Dave</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Eve</span></div><div class="b4"><span class="v">Eve</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Frank</span></div><div class="b4"><span class="v">Frank</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Grace</span></div><div class="b4"><span class="v">Grace</span><span class="w">Developer</span></div><div class="b5"></div></div><div class="b3"><div class="t"><span>Hank</span></div><div class="b4"><span class="v">Hank</span><span class="w">Developer</span></div><div class="b5"></div></div></div></div></div><div class="aw"><span class="ax">Tags</span><div class="ay"><div class="b6"><div class="b7"><span>frontend</span></div><div class="b7"><span>backend</span></div><div class="b7"><span>devops</span></div><div class="b7"><span>design</span></div><div class="b7"><span>mobile</span></div><div class="b7"><span>security</span></div><div class="b7"><span>performance</span></div><div class="b7"><span>testing</span></div><div class="b7"><span>docs</span></div><div class="b7"><span>infra</span></div><div class="b7"><span>ux</span></div><div class="b7"><span>api</span></div></div></div></div><div class="aw"><span class="ax">Notifications</span><div class="ay"><div class="bi"><div class="b8"><div class="al"></div><span class="br">New deployment completed</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">PR review requested</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Build failed on staging</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Meeting in 30 minutes</span><span class="w">now</span></div><div class="b8"><div class="al"></div><span class="br">Subscription renewal due</span><span class="w">now</span></div></div></div></div><div class="aw"><span class="ax">Settings</span><div class="ay"><div class="bc"><div class="b9"><span class="by">Dark Mode</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Notifications</span><div class="ca"><div class="cb"></div></div></div><div class="b9"><span class="by">Auto-save</span><div class="cc"><div class="cd"></div></div></div><div class="b9"><span class="by">Compact View</span><div class="cc"><div class="cd"></div></div></div></div></div></div></div></div><div class="ce"><div class="aw"><span class="ax">Data Table</span><div class="ay"><div class="bi"><div class="cf"><input class="cg" type="search" placeholder="Filter results..."><div class="af"></div><div class="aa"><button class="ch">all</button><button class="ch">design</button><button class="ch">development</button><button class="ch">marketing</button><button class="ch">analytics</button></div></div><div class="ci"><div class="cj"><span class="bl">ID</span></div><div class="bk"><span class="bl">Name</span></div><div class="bm"><span class="bl">Category</span></div><div class="bn"><span class="bl">Status</span></div><div class="af"><span class="bl">Updated</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">active</span></div><div class="bn"><div class="cn"><span>active</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">pending</span></div><div class="bn"><div class="cn"><span>pending</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">completed</span></div><div class="bn"><div class="cn"><span>completed</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Alpha</span></div><span class="cm">Alpha</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Beta</span></div><span class="cm">Beta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Gamma</span></div><span class="cm">Gamma</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Delta</span></div><span class="cm">Delta</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="ck"><div class="cj"><span class="p">#42</span></div><div class="bk"><div class="n"><div class="cl"><span>Epsilon</span></div><span class="cm">Epsilon</span></div></div><div class="bm"><span class="p">archived</span></div><div class="bn"><div class="cn"><span>archived</span></div></div><div class="af"><span class="p">2 hours ago</span></div></div><div class="co"><span class="p">Showing 1-20 of 142 results</span><div class="af"></div><div class="cp"><button class="cq">Prev</button><button class="cr">1</button><button class="cq">2</button><button class="cq">3</button><button class="cq">Next</button></div></div></div></div></div></div></div><footer class="cs"><div class="ct"><div class="cu"><span class="cv">htmlang Dashboard</span><span class="g">Built with htmlang - a declarative HTML language</span><span class="w">Copyright 2025 htmlang contributors</span></div><div class="m"><span class="cw">Product</span><a href="/features" class="cx">Features</a><a href="/pricing" class="cx">Pricing</a><a href="/changelog" class="cx">Changelog</a><a href="/roadmap" class="cx">Roadmap</a></div><div class="m"><span class="cw">Resources</span><a href="/docs" class="cx">Documentation</a><a href="/api" class="cx">API Reference</a><a href="/guides" class="cx">Guides</a><a href="/examples" class="cx">Examples</a></div><div class="m"><span class="cw">Company</span><a href="/about" class="cx">About</a><a href="/blog" class="cx">Blog</a><a href="/careers" class="cx">Careers</a><a href="/contact" class="cx">Contact</a></div><div class="m"><span class="cw">Legal</span><a href="/privacy" class="cx">Privacy Policy</a><a href="/terms" class="cx">Terms of Service</a><a href="/cookies" class="cx">Cookie Policy</a></div></div></footer></div></div></body></html>