pub const DEFAULT: &str = "/*\n * lumen-skin-default - embedded user-agent stylesheet, opt-in.\n *\n * Activated by setting `<root skin=\"default\">`. The bare framework still\n * ships zero baked-in styling (SDD section 1.3 \"Decoupled Rendering\" - apps\n * that don\'t opt in render visually blank). Override anything below in\n * the app\'s own `main.css`; HTML inline attributes win over both.\n *\n * Design tokens used here are NOT design tokens in the `<theme>` sense;\n * they\'re literal default values. Apps that want to retheme should\n * either author their own skin, set explicit attrs / classes, or\n * redeclare the `--lumen-*` custom properties below in their own\n * `:root { }` block (the theme/media re-resolver merges skin + app\n * custom properties into one cascade on every reapply, so a single\n * app-side `:root` block can retint every widget covered here).\n *\n * Coverage: button, input, textarea, toggle, switch, slider, tile\n * (interactive surfaces), checkbox, radio, progress, dropdown (R4.1),\n * menu (R4.2), dialog (backdrop + opt-in `.dialog-surface`), tabs,\n * tooltip, and a focus outline for keyboard-focusable `<scroll>`\n * regions. Also carries the caret / line-height /\n * scrollbar-geometry tokens consumed by `<input>` / `<textarea>` /\n * `<scroll>` even where this file sets no per-selector rule for them.\n *\n * Every rule below stays inside the CSS subset documented in\n * docs/src/authoring/css.md - state pseudos (`:hover` / `:focus` /\n * `:focus-visible` / `:active` / `:checked` / `:disabled` / `:selected`)\n * only ever route `bg`, `border` (hover/focus), or `outline` under\n * `:focus`; no other property\n * is state-aware yet. `:selected` (`.tab-btn:selected` below) routes to\n * `Attributes::selected_bg`, which `lumenc::spawn` hands to\n * `lumen_primitives::tabs::TabButtonStyle`; the runtime swaps the fill as\n * the `Selected` marker moves between tab-strip siblings.\n */\n\n/* === Tokens ===\n * One block to override for a full re-theme.\n */\n:root {\n /* Action-control fills: button, input, dropdown header, tab strip well */\n --lumen-surface: #0a3358;\n --lumen-surface-hover: #114570;\n --lumen-surface-active: #073056;\n\n /* Toggle / slider track (neutral groove, not an action color) */\n --lumen-track: #3a3a3a;\n --lumen-track-hover: #565656;\n --lumen-track-active: #2e2e2e;\n\n /* Elevated / floating surfaces: dropdown panel, menu panel, dialog\n surface, tooltip. A touch darker + richer than the action fills so\n popovers read as \"above\" the controls that open them. */\n --lumen-panel: #0c2c4a;\n --lumen-panel-hover: #163a5c;\n /* Max dropdown-popup height before it scrolls internally: 9 x 32 px\n option rows (Qt\'s maxVisibleItems ~ 10). `.dropdown-panel` pairs\n this with `overflow-y: scroll`; keyboard highlight movement keeps\n the current row scrolled into view. */\n --lumen-dropdown-max-height: 288;\n --lumen-border: #1c4666;\n /* Subtle hairline for resting field / card chrome; --lumen-border is\n the stronger tone reserved for elevated panels + separators. */\n --lumen-border-subtle: #16395a;\n\n /* Text */\n --lumen-text: #ffffff;\n --lumen-text-muted: #a9b8c9;\n /* Text-selection highlight. The fill is opaque so it reads on any\n field colour an app authors, not just on this skin\'s own surface,\n and the glyphs are redrawn in the paired foreground on top of it.\n Both halves are needed: a tint alone disappears against a light\n field, and an opaque fill alone swallows the text. */\n --lumen-selection: var(--lumen-accent);\n --lumen-selection-text: #062028;\n\n /* Accent (focus rings, checked track, selected tab) */\n --lumen-accent: #33c7ce;\n\n /* Disabled fill: low-contrast, still readable as \"off\" */\n --lumen-disabled-bg: #123047;\n\n /* Chrome */\n --lumen-radius-sm: 6;\n --lumen-radius: 8;\n --lumen-radius-lg: 14;\n --lumen-shadow-panel: 0 6 18 #00000088;\n --lumen-shadow-dialog: 0 12 32 #000000aa;\n --lumen-backdrop: #00000099;\n\n /* Overlay scrollbars (CSS Scrollbars Styling L1: scrollbar-color /\n scrollbar-width). Thumb only - the default overlay convention shows\n the translucent track on hover; declare a second color here to get\n an always-painted track instead. */\n --lumen-scrollbar-thumb: #a9b8c98c;\n\n /* Tooltip: hover dwell (ms) before the popup appears and the gap (px)\n between the cursor hotspot and the popup\'s top-left corner. Markup\n `delay=` / `offset=` attrs override per-trigger. */\n --lumen-tooltip-delay: 500;\n --lumen-tooltip-offset: 12;\n\n /* Indeterminate <progress> sweep period, ms per full bounce, and the\n fraction of the track width the moving chunk covers. */\n --lumen-progress-period: 1200;\n --lumen-progress-chunk: 0.3;\n\n /* Toggle / switch knob inset (px, gap from the track edge) and the\n slider thumb\'s fixed diameter (px). */\n --lumen-knob-inset: 4;\n --lumen-thumb-size: 16;\n\n /* Gap (px) between a dropdown/menu trigger and its floating panel. */\n --lumen-popup-gap: 4;\n\n /* Opacity applied to a disabled control when neither its `:disabled`\n rule nor an explicit `disabled-bg` already dims it. */\n --lumen-disabled-opacity: 0.5;\n\n /* Text-input caret: stroke width (px) and full on/off blink period. */\n --lumen-caret-width: 2;\n --lumen-caret-blink: 530ms;\n\n /* Line-height as a unitless multiplier of the element\'s font size\n (matches the CSS `normal` keyword\'s usual ~1.2 ratio). */\n --lumen-line-height: 1.2;\n\n /* Overlay scrollbar geometry, hover feedback and fade timing for\n `<scroll>` containers, alongside the `--lumen-scrollbar-thumb`\n color above. */\n --lumen-scrollbar-thickness: 8;\n --lumen-scrollbar-thickness-thin: 4;\n --lumen-scrollbar-margin: 2;\n --lumen-scrollbar-min-thumb: 24;\n --lumen-scrollbar-track-hover: #80808029;\n --lumen-scrollbar-hover-boost: 1.6;\n --lumen-scrollbar-fade-delay: 1000ms;\n --lumen-scrollbar-fade-duration: 250ms;\n}\n\n@media (prefers-color-scheme: dark) {\n /* The palette above is already dark-first; OS dark mode just widens\n contrast a little further instead of flipping hues. Apps that want\n an actual light skin should override the whole token block above,\n not this one. */\n :root {\n --lumen-panel: #091f34;\n --lumen-text-muted: #bccbdb;\n --lumen-backdrop: #000000b3;\n }\n}\n\n/* === Buttons ===\n * `transition: bg` routes the hover / press tint tween through the CSS\n * timing (see lumen-primitives::hover) - 130 ms ease reads as crisp\n * without feeling instant.\n */\nbutton { bg: var(--lumen-surface); radius: var(--lumen-radius); padding: 8 16; text-color: var(--lumen-text); transition: bg 130ms ease; }\n/* Dialog default button (`<button default=\"true\">` gains the class at\n * parse time): Qt\'s default-button ring - Enter anywhere in the open\n * dialog activates it. */\nbutton.default { border: 2px solid var(--lumen-accent); }\nbutton:hover { bg: var(--lumen-surface-hover); }\nbutton:active { bg: var(--lumen-surface-active); }\nbutton:focus { outline: 2 var(--lumen-accent); }\nbutton:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Inputs ===\n * Real borders (R-css-flex): a resting 1px hairline so fields read as\n * fields without focus, the accent outline on focus (outline draws\n * outside the box and never shifts layout - CSS outline semantics),\n * and a brighter hover border. box-sizing defaults to border-box, so\n * the 1px chrome never changes an authored width. `selection-color`\n * feeds the text-edit selection highlight (--lumen-selection token).\n */\ninput { bg: var(--lumen-surface); radius: var(--lumen-radius); padding: 8 12; text-color: var(--lumen-text); border: 1px solid var(--lumen-border-subtle); transition: bg 130ms ease; selection-color: var(--lumen-selection); selection-text-color: var(--lumen-selection-text); caret-width: var(--lumen-caret-width); caret-blink: var(--lumen-caret-blink); }\ninput:hover { bg: var(--lumen-surface-hover); border: 1px solid var(--lumen-border); }\ninput:focus { outline: 2 var(--lumen-accent); }\ninput:disabled { bg: var(--lumen-disabled-bg); }\n\ntextarea { bg: var(--lumen-surface); radius: var(--lumen-radius); padding: 8 12; text-color: var(--lumen-text); border: 1px solid var(--lumen-border-subtle); transition: bg 130ms ease; selection-color: var(--lumen-selection); selection-text-color: var(--lumen-selection-text); caret-width: var(--lumen-caret-width); caret-blink: var(--lumen-caret-blink); }\ntextarea:hover { bg: var(--lumen-surface-hover); border: 1px solid var(--lumen-border); }\ntextarea:focus { outline: 2 var(--lumen-accent); }\ntextarea:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Toggles ===\n * Track + knob are both styled here: `knob-color` is the Lumen-native\n * analog property for the knob child spawned by lumenc::spawn (the\n * value below matches the runtime KNOB_FILL fallback used when no skin\n * or author CSS supplies one). Knob geometry stays runtime-driven\n * (sync_toggle_visuals).\n */\ntoggle { bg: var(--lumen-track); radius: 12; knob-color: #ebebf0; knob-inset: var(--lumen-knob-inset); transition: bg 130ms ease; }\ntoggle:hover { bg: var(--lumen-track-hover); }\ntoggle:active { bg: var(--lumen-track-active); }\ntoggle:focus { outline: 2 var(--lumen-accent); }\ntoggle:checked { bg: var(--lumen-accent); }\ntoggle:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Switch ===\n * `<switch>` is the pill-shaped on/off control (distinct element from\n * `<toggle>`, same underlying track/knob colors so the two read as one\n * family). Its own unstyled default height is a true 28px pill, so it\n * gets a fuller radius than toggle\'s 36px slab. `knob-inset` places the\n * thumb in from the track edge; the thumb\'s slide animation reuses this\n * rule\'s `transition` duration/easing (same TransitionSpecs lookup\n * hover.rs already uses for tint tweens, repointed at the slide).\n */\nswitch { bg: var(--lumen-track); radius: 14; knob-color: #ebebf0; knob-inset: var(--lumen-knob-inset); transition: bg 140ms ease-out; }\nswitch:hover { bg: var(--lumen-track-hover); }\nswitch:active { bg: var(--lumen-track-active); }\nswitch:focus { outline: 2 var(--lumen-accent); }\nswitch:checked { bg: var(--lumen-accent); }\nswitch:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Sliders ===\n * Same story as toggle: the thumb child (SliderThumb) takes the\n * `knob-color` fill; `thumb-size` is its fixed diameter (unlike the\n * toggle/switch knob, which derives from track height).\n */\nslider { bg: var(--lumen-track); radius: 4; knob-color: #ebebf0; thumb-size: var(--lumen-thumb-size); }\nslider:hover { bg: var(--lumen-track-hover); }\nslider:focus { outline: 2 var(--lumen-accent); }\nslider:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Checkbox ===\n * `<checkbox label=\"...\">` desugars (lumenc::parse::html) to:\n * checkbox (row, carries Toggleable)\n * .checkbox-box (tag=tile - the indicator; check / dash mark drawn as text)\n * .checkbox-label (tag=label)\n * `:checked { bg }` routes to the box fill swap (runtime\n * sync_checkbox_visuals); the resting box look lives on `.checkbox-box`.\n * On the web the box is the browser\'s own control under that same class,\n * so these rules reach both targets.\n */\ncheckbox { disabled-opacity: var(--lumen-disabled-opacity); }\ncheckbox:checked { bg: var(--lumen-accent); }\ncheckbox:focus { outline: 2 var(--lumen-accent); }\n.checkbox-box { width: 18; height: 18; radius: 4; bg: var(--lumen-surface); border: 1px solid var(--lumen-border); text-color: #ffffff; font-size: 14; text-align: center; }\n.checkbox-label { text-color: var(--lumen-text); }\n\n/* === Radio ===\n * `<radio group=\"g\" value=\"v\" label=\"...\">` desugars to:\n * radio (row, carries RadioButton)\n * .radio-dot (tag=tile - round indicator)\n * .radio-label (tag=label)\n * `:selected { bg }` routes to the dot fill swap (sync_radio_visuals); the\n * web draws the dot as the browser\'s own control under the same class.\n */\nradio { disabled-opacity: var(--lumen-disabled-opacity); }\nradio:selected { bg: var(--lumen-accent); }\nradio:focus { outline: 2 var(--lumen-accent); }\n.radio-dot { width: 18; height: 18; radius: 9; bg: var(--lumen-surface); border: 1px solid var(--lumen-border); }\n.radio-label { text-color: var(--lumen-text); }\n\n/* === Progress ===\n * `<progress>` desugars to a track (tag=progress) + `.progress-fill`\n * child whose width (determinate) / sweep offset (indeterminate) is\n * runtime-driven; everything visual is declared here.\n */\nprogress { bg: var(--lumen-track); radius: 3; height: 6; progress-duration: var(--lumen-progress-period); progress-chunk: var(--lumen-progress-chunk); }\n.progress-fill { bg: var(--lumen-accent); radius: 3; }\n\n/* === Generic tiles (interactive surfaces) === */\ntile:hover { bg: var(--lumen-surface-hover); }\ntile:active { bg: var(--lumen-surface-active); }\ntile:focus { outline: 2 var(--lumen-accent); }\ntile:disabled { bg: var(--lumen-disabled-bg); }\n\n/* === Dropdown (R4.1) ===\n * `<dropdown bind-value>` + `<option>` desugars (lumenc::parse::html) to:\n * .dropdown (column, positioning wrapper)\n * .dropdown-button (tag=button - the header)\n * .dropdown-panel (tag=column, absolute below the header)\n * .dropdown-option (tag=button, one per <option>)\n */\n.dropdown-button { bg: var(--lumen-surface); radius: var(--lumen-radius-sm); text-color: var(--lumen-text); text-overflow: ellipsis; }\n.dropdown-button:hover { bg: var(--lumen-surface-hover); }\n.dropdown-button:active { bg: var(--lumen-surface-active); }\n.dropdown-button:focus { outline: 2 var(--lumen-accent); }\n\n.dropdown-panel {\n transition: opacity 120ms ease;\n bg: var(--lumen-panel);\n radius: var(--lumen-radius-sm);\n shadow: var(--lumen-shadow-panel);\n border: 1px solid var(--lumen-border);\n padding: 4 0;\n /* Max-visible-rows: past this height the panel scrolls internally\n (`overflow-y: scroll` promotes it to a live scroll container). */\n max-height: var(--lumen-dropdown-max-height);\n overflow-y: scroll;\n /* Gap from the trigger button this panel is anchored to. */\n popup-gap: var(--lumen-popup-gap);\n}\n\n/* The keyboard highlight IS the focus marker on the option row, and\n * the hover-tint path treats focus like hover - so `:hover` here\n * styles BOTH the pointer highlight and the keyboard highlight (one\n * shared state, Qt-style); `:focus` adds the keyboard ring. */\n.dropdown-option { bg: var(--lumen-panel); text-color: var(--lumen-text); text-align: start; transition: bg 130ms ease; text-overflow: ellipsis; disabled-opacity: var(--lumen-disabled-opacity); }\n.dropdown-option:hover { bg: var(--lumen-panel-hover); }\n.dropdown-option:focus { outline: 2 var(--lumen-accent); }\n.dropdown-option:disabled { text-color: var(--lumen-text-muted); }\n\n/* === Menu (R4.2) ===\n * A standalone `<menu id>` desugars to:\n * .menu-panel (tag=overlay, absolute-positioned)\n * .menu-item (tag=button, one per <menuitem>)\n * .menu-separator (tag=spacer, one per <separator>)\n *\n * `<menu>` nested inside `<menubar>` is native OS chrome - extracted by\n * `extract_menubar` before the layout tree is built, so it never\n * reaches this (or any) stylesheet. There is intentionally no\n * `menubar` selector here.\n */\n.menu-panel {\n transition: opacity 120ms ease;\n bg: var(--lumen-panel);\n radius: var(--lumen-radius-sm);\n shadow: var(--lumen-shadow-panel);\n border: 1px solid var(--lumen-border);\n padding: 4 0;\n popup-gap: var(--lumen-popup-gap);\n}\n\n.menu-item { bg: var(--lumen-panel); text-color: var(--lumen-text); text-align: start; transition: bg 130ms ease; disabled-opacity: var(--lumen-disabled-opacity); }\n.menu-item:hover { bg: var(--lumen-panel-hover); }\n.menu-item:focus { outline: 2 var(--lumen-accent); }\n.menu-item:disabled { text-color: var(--lumen-text-muted); }\n\n.menu-separator { bg: var(--lumen-border); height: 1; margin: 4 0; }\n\n/* === Dialog ===\n * `<dialog>` itself IS the full-screen absolute overlay (the parser\n * seeds position:absolute + inset:0 on the tag), so it gets a dim\n * scrim rather than a card look. `.dialog-surface` is an opt-in\n * convention class an app can put on its actual modal content (in\n * place of a bespoke `.card`-alike) to get a default-styled surface.\n */\n/* Entering transition: the dialog overlay (scrim + surface via\n * inherited opacity) fades in over 150 ms when its open signal flips.\n * Mount-direction only - closing is instant (removal transitions need\n * JS even on the web). */\ndialog { bg: var(--lumen-backdrop); transition: opacity 150ms ease; }\n\n.dialog-surface {\n bg: var(--lumen-panel);\n radius: var(--lumen-radius-lg);\n shadow: var(--lumen-shadow-dialog);\n border: 1px solid var(--lumen-border);\n padding: 24;\n}\n\n/* === Cards ===\n * `.card` is the opt-in convention class for a content tile - mirrors\n * `.dialog-surface`. Resting chrome only; interactive `tile` states\n * stay in the tile block above.\n */\n.card {\n bg: var(--lumen-panel);\n radius: var(--lumen-radius);\n border: 1px solid var(--lumen-border-subtle);\n padding: 16;\n}\n\n\n/* === Tabs ===\n * `<tabs bind-value>` desugars to:\n * .tabs (column)\n * .tab-strip (row)\n * .tab-btn (tag=button, one per <tab>)\n *\n * The active tab carries the `Selected` marker (kept in sync from the\n * bound signal by lumen_primitives::tabs::sync_tab_selected);\n * lumen_primitives::tabs::sync_tab_button_visuals paints the `:selected`\n * bg rule below as the marker moves between siblings (see file header).\n */\n.tab-strip { bg: var(--lumen-surface); radius: var(--lumen-radius-sm); padding: 4; gap: 4; }\n\n/* Qt QTabBar elide contract: overlong tab titles elide with `...`\n * instead of widening the strip. */\n.tab-btn { bg: #00000000; radius: var(--lumen-radius-sm); text-color: var(--lumen-text-muted); transition: bg 130ms ease; text-overflow: ellipsis; disabled-opacity: var(--lumen-disabled-opacity); }\n.tab-btn:hover { bg: var(--lumen-surface-hover); }\n.tab-btn:focus { outline: 2 var(--lumen-accent); }\n.tab-btn:selected { bg: var(--lumen-accent); }\n.tab-btn:disabled { text-color: var(--lumen-text-muted); }\n\n/* === Tooltip ===\n * `<tooltip text=\"...\">` flattens onto its trigger child; the runtime\n * spawns a popup entity classed `tooltip`\n * (lumen_primitives::tooltip::spawn_tooltip_popups) that this rule\n * targets directly.\n */\n.tooltip { bg: #0b0e13ee; text-color: #ffffff; radius: var(--lumen-radius-sm); shadow: var(--lumen-shadow-panel); border: 1px solid var(--lumen-border); padding: 6 10; }\n\n/* === Scroll region ===\n * `<scroll>` wraps arbitrary author content, so it otherwise stays\n * unstyled here - a focus outline for the opt-in case where an author\n * gives a scroll region `tab-index` for keyboard scrolling, plus the\n * overlay-scrollbar thumb tint (the fade / hover behavior is the\n * runtime\'s; only colors and width are CSS surface).\n */\nscroll {\n scrollbar-color: var(--lumen-scrollbar-thumb);\n scrollbar-thickness: var(--lumen-scrollbar-thickness);\n scrollbar-thickness-thin: var(--lumen-scrollbar-thickness-thin);\n scrollbar-margin: var(--lumen-scrollbar-margin);\n scrollbar-min-thumb: var(--lumen-scrollbar-min-thumb);\n scrollbar-track-hover: var(--lumen-scrollbar-track-hover);\n scrollbar-hover-boost: var(--lumen-scrollbar-hover-boost);\n scrollbar-fade-delay: var(--lumen-scrollbar-fade-delay);\n scrollbar-fade-duration: var(--lumen-scrollbar-fade-duration);\n}\nscroll:focus { outline: 2 var(--lumen-accent); }\n\n/* === Root ===\n * `line-height` is the one root-level typography token this file sets;\n * font-family / font-size stay with the always-on user-agent baseline\n * so a skinless app still gets sane text sizing (see the file header).\n */\nroot { line-height: var(--lumen-line-height); }\n";Expand description
Default (neutral, dark-first) skin CSS for buttons, inputs, toggles, sliders, and tiles.