/* Tabs mapping: default Primary Fill (content), Secondary Fill (surface), Legacy non-fill and overflow move buttons (D-090). Horizontal, text-only, no size/variant. States use Radix attributes: [data-state="active"|"inactive"], :hover, :focus-visible. */ :root, [data-hm-theme] { /* ui_viz: docs/components/tabs.md §8, §16 — SOURCE_ADOPTED / COMPONENT_SCOPED (owner 2026-09-18). Not aliased to Button or radius/border tokens. */ --hm-tab-height: 34px; --hm-tab-padding-x: 16px; --hm-tab-radius-top: 4px; --hm-tab-border-width: 1px; /* ui_viz: docs/components/tabs.md §9 — Navigation Label 16/24/700, same weight for Selected */ --hm-tab-font-size: 16px; --hm-tab-line-height: 24px; --hm-tab-font-weight: 700; /* ui_viz: docs/components/tabs.md §10 — SOURCE_ADOPTED. Default face and border are also marked TEMPORARY there (alpha composites of Green tint / Green Light 2). Selected border is #DEDBD2 (color.stroke.tab.selected); no Semantic exists in HM, so the Primitive is used here. */ --hm-tab-background: color-mix(in srgb, var(--hm-sem-palette-green-tint) 45%, transparent); --hm-tab-border-color: color-mix(in srgb, var(--hm-sem-palette-green-light-2) 35%, transparent); --hm-tab-text: var(--hm-sem-palette-green-light-2); --hm-tab-selected-background: var(--hm-sem-bg-surface); --hm-tab-selected-border-color: var(--hm-sem-stroke-input-default); --hm-tab-selected-text: var(--hm-sem-action-primary); /* Hover (inactive only): Black 20% overlay — value Confirmed (tab.md 6, 8); foreground SOURCE_ADOPTED */ --hm-tab-hover-overlay: color-mix(in srgb, var(--hm-sem-palette-black) 20%, transparent); --hm-tab-hover-text: var(--hm-sem-action-primary); --hm-tab-transition-duration: 0.15s; } /* Frame holds the Bar (and the move buttons when the tabs overflow). The whole Bar overlaps the content boundary by 1px; Selected paints its bottom stroke in the surface color. */ [data-slot="tabs-frame"] { display: flex; align-items: flex-end; width: 100%; margin-bottom: -1px; } /* Bar: no surface of its own, gap 0, scrolls horizontally with the native scrollbar hidden. */ [data-slot="tabs-list"] { display: flex; align-items: flex-end; flex: 0 1 auto; gap: 0; min-width: 0; max-width: 100%; padding: 0; border: 0; border-radius: 0; background: transparent; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; } [data-slot="tabs-trigger"] { box-sizing: border-box; height: var(--hm-tab-height); min-height: var(--hm-tab-height); padding: 0 var(--hm-tab-padding-x); border: var(--hm-tab-border-width) solid var(--hm-tab-border-color); border-bottom-color: var(--hm-tab-selected-border-color); border-radius: var(--hm-tab-radius-top) var(--hm-tab-radius-top) 0 0; background-color: var(--hm-tab-background); background-image: none; color: var(--hm-tab-text); font-size: var(--hm-tab-font-size); line-height: var(--hm-tab-line-height); font-weight: var(--hm-tab-font-weight); box-shadow: none; transition: color var(--hm-tab-transition-duration) ease, background-color var(--hm-tab-transition-duration) ease; } /* One shared border between neighbours. Must come before the Selected rule. */ [data-slot="tabs-trigger"] + [data-slot="tabs-trigger"] { border-left-width: 0; } [data-slot="tabs-trigger"][data-state="active"] { z-index: 2; border-color: var(--hm-tab-selected-border-color); border-bottom-color: var(--hm-tab-selected-background); background-color: var(--hm-tab-selected-background); color: var(--hm-tab-selected-text); } [data-slot="tabs-trigger"][data-state="inactive"]:hover:not(:disabled) { background-image: linear-gradient(var(--hm-tab-hover-overlay), var(--hm-tab-hover-overlay)); color: var(--hm-tab-hover-text); } /* Focus is a global TBD in ui_viz: the shadcn focus ring from ui/tabs.tsx stays. The theme box-shadow is none, so keep the ring variables. */ [data-slot="tabs-trigger"]:focus-visible { box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000); } /* ---- Overflow move buttons (ui_viz tabs.md §24 D-090, CURRENT 2026-10-01). Outside the tablist, shown only when the tabs overflow. ---- */ :root, [data-hm-theme] { --hm-tab-arrow-size: 34px; --hm-tab-arrow-icon-size: 18px; --hm-tab-arrow-background: var(--hm-sem-palette-green-light-1); --hm-tab-arrow-border-color: var(--hm-sem-palette-green-dark-1); --hm-tab-arrow-icon-color: var(--hm-sem-on-action-primary); --hm-tab-arrow-disabled-opacity: 0.6; } [data-slot="tabs-frame"][data-overflow="true"] > [data-slot="tabs-list"] { flex: 1 1 0; } [data-slot="tabs-arrow"] { display: inline-flex; flex: none; align-items: center; justify-content: center; box-sizing: border-box; width: var(--hm-tab-arrow-size); height: var(--hm-tab-arrow-size); padding: 0; border: var(--hm-tab-border-width) solid var(--hm-tab-arrow-border-color); background-color: var(--hm-tab-arrow-background); background-image: none; color: var(--hm-tab-arrow-icon-color); cursor: pointer; outline: none; } [data-slot="tabs-arrow"][data-direction="previous"] { border-radius: var(--hm-tab-radius-top) 0 0 0; } [data-slot="tabs-arrow"][data-direction="next"] { border-radius: 0 var(--hm-tab-radius-top) 0 0; } [data-slot="tabs-arrow"] svg { width: var(--hm-tab-arrow-icon-size); height: var(--hm-tab-arrow-icon-size); } [data-slot="tabs-arrow"]:hover:not(:disabled) { background-image: linear-gradient(var(--hm-tab-hover-overlay), var(--hm-tab-hover-overlay)); } [data-slot="tabs-arrow"]:disabled { opacity: var(--hm-tab-arrow-disabled-opacity); cursor: default; pointer-events: none; } /* Focus value is global TBD: shadcn ring level kept (ring variables come from the tailwind focus-visible utilities). */ [data-slot="tabs-arrow"]:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--ring) 50%, transparent); } /* In the overflow state every item keeps its own label width (no equal split). */ [data-slot="tabs-frame"][data-overflow="true"] [data-slot="tabs-trigger"] { flex: 0 0 auto; } /* ---- Fill profile (ui_viz tabs.md §24 D-071~075): default Primary content; explicit surface is Secondary. ---- */ :root, [data-hm-theme] { --hm-tab-fill-line-color: var(--hm-sem-palette-green-light-3); /* REVIEW VALUE (ui_viz tabs.md §24: curve radius 8px, BORDER FOLLOW-UP). The curve itself is Confirmed, the radius is not. */ --hm-tab-fill-curve-radius: 8px; } [data-slot="tabs-frame"][data-fill="true"] { --hm-tab-fill-panel: var(--hm-sem-bg-surface); --hm-tab-fill-face: linear-gradient(var(--hm-sem-bg-surface), var(--hm-sem-bg-surface)); } [data-slot="tabs-frame"][data-fill="true"][data-panel-surface="content"] { --hm-tab-fill-panel: var(--hm-sem-bg-content); /* D-02 (2026-10-09): only Primary's selected face starts at White alpha .8; the content stop, direction and geometry stay unchanged. */ --hm-tab-fill-face: linear-gradient(to bottom, color-mix(in srgb, var(--hm-sem-palette-white) 80%, transparent) 0%, var(--hm-sem-bg-content) 100%); } [data-slot="tabs-frame"][data-fill="true"] > [data-slot="tabs-list"] { flex: 1 1 auto; width: 100%; } [data-slot="tabs-frame"][data-fill="true"][data-overflow="false"] [data-slot="tabs-trigger"] { flex: 1 1 0; min-width: auto; } /* Inactive: only the bottom line is Green Light 3; face and top / vertical borders keep the basic profile values. */ [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"] { border-bottom-color: var(--hm-tab-fill-line-color); } /* Every fill neighbour restores its left border and overlaps it by 1px, matching the tested ui-viz geometry. The active tab's z-index keeps its Green edge above the inactive border without producing a double-width line. */ [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"] + [data-slot="tabs-trigger"] { margin-left: calc(-1 * var(--hm-tab-border-width)); border-left-width: var(--hm-tab-border-width); } /* Selected: Green Light 3 top / left / right, bottom open in the panel color. */ [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"][data-state="active"] { border-color: var(--hm-tab-fill-line-color); border-bottom-color: var(--hm-tab-fill-panel); background-color: transparent; background-image: var(--hm-tab-fill-face); } /* Curves: a quarter arc of the vertical Green line toward each neighbour, 1px Green. Inside the arc is transparent (the neighbour shows), outside is the panel color. Decoration only: no pointer input. */ [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"][data-state="active"]:not(:last-child)::after, [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"][data-state="active"]:not(:first-child)::before { content: ""; position: absolute; bottom: calc(-1 * var(--hm-tab-border-width)); width: var(--hm-tab-fill-curve-radius); height: var(--hm-tab-fill-curve-radius); pointer-events: none; } [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"][data-state="active"]:not(:last-child)::after { right: calc(-1 * var(--hm-tab-fill-curve-radius)); background: radial-gradient(circle at 100% 0, transparent calc(var(--hm-tab-fill-curve-radius) - var(--hm-tab-border-width)), var(--hm-tab-fill-line-color) calc(var(--hm-tab-fill-curve-radius) - var(--hm-tab-border-width)), var(--hm-tab-fill-line-color) var(--hm-tab-fill-curve-radius), var(--hm-tab-fill-panel) var(--hm-tab-fill-curve-radius)); } [data-slot="tabs-frame"][data-fill="true"] [data-slot="tabs-trigger"][data-state="active"]:not(:first-child)::before { left: calc(-1 * var(--hm-tab-fill-curve-radius)); background: radial-gradient(circle at 0 0, transparent calc(var(--hm-tab-fill-curve-radius) - var(--hm-tab-border-width)), var(--hm-tab-fill-line-color) calc(var(--hm-tab-fill-curve-radius) - var(--hm-tab-border-width)), var(--hm-tab-fill-line-color) var(--hm-tab-fill-curve-radius), var(--hm-tab-fill-panel) var(--hm-tab-fill-curve-radius)); }