fernwell 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +13 -5
- package/dist/_position.d.ts +73 -0
- package/dist/fernwell.cjs +3 -3
- package/dist/fernwell.cjs.map +4 -4
- package/dist/fernwell.css +484 -8
- package/dist/fernwell.esm.js +3 -3
- package/dist/fernwell.esm.js.map +4 -4
- package/dist/fernwell.iife.js +3 -3
- package/dist/fernwell.iife.js.map +4 -4
- package/dist/fernwell.min.css +2 -2
- package/dist/fernwell.tokens.css +7 -1
- package/dist/icon.d.ts +16 -0
- package/dist/index.d.ts +13 -1
- package/dist/popover.d.ts +48 -0
- package/dist/tabs.d.ts +43 -0
- package/dist/theme.d.ts +0 -13
- package/dist/tokens.json +12 -0
- package/dist/tooltip.d.ts +51 -0
- package/package.json +10 -5
package/dist/fernwell.min.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! fernwell v0.
|
|
2
|
-
@layer fw-tokens{:root,[data-theme=light]{--fw-text: #1F2430;--fw-text-soft: #565D6E;--fw-bg: #F5F6F1;--fw-bg-dim: #EAEBE4;--fw-surface: #FFFFFF;--fw-primary: #FFC145;--fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);--fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);--fw-secondary: #4C3A73;--fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);--fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 10%, var(--fw-surface));--fw-success: #3FA672;--fw-success-bg: color-mix(in srgb, var(--fw-success) 12%, var(--fw-surface));--fw-warning: #E8A521;--fw-warning-bg: color-mix(in srgb, var(--fw-warning) 14%, var(--fw-surface));--fw-danger: #E85B4F;--fw-danger-bg: color-mix(in srgb, var(--fw-danger) 13%, var(--fw-surface));--fw-info: #3E8FD0;--fw-info-bg: color-mix(in srgb, var(--fw-info) 12%, var(--fw-surface));--fw-on-primary: #1F2430;--fw-on-secondary: #FFFFFF;--fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);--fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);--fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);--fw-overlay: rgba(31, 36, 48, .55);--fw-overlay-soft: rgba(31, 36, 48, .32);--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);--fw-font-display: "Plus Jakarta Sans", system-ui, sans-serif;--fw-font-body: "Inter", system-ui, sans-serif;--fw-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--fw-sp-1: 4px;--fw-sp-2: 8px;--fw-sp-3: 12px;--fw-sp-4: 16px;--fw-sp-5: 24px;--fw-sp-6: 32px;--fw-sp-7: 48px;--fw-sp-8: 64px;--fw-sp-9: 96px;--fw-r-sm: 10px;--fw-r-md: 16px;--fw-r-lg: 24px;--fw-r-xl: 32px;--fw-r-full: 999px;--fw-shadow-sm: 0 1px 2px rgba(31, 36, 48, .06), 0 1px 1px rgba(31, 36, 48, .04);--fw-shadow-md: 0 4px 12px rgba(31, 36, 48, .08), 0 2px 4px rgba(31, 36, 48, .04);--fw-shadow-lg: 0 12px 32px rgba(31, 36, 48, .12), 0 4px 8px rgba(31, 36, 48, .06);--fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 35%, transparent);--fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 28%, transparent);--fw-border-w: 1.5px;--fw-motion-fast: .12s;--fw-motion-base: .18s;--fw-motion-ease: ease}[data-theme=dark]{--fw-text: #F2F1EA;--fw-text-soft: #9CA1B0;--fw-bg: #14161C;--fw-bg-dim: #2B2F3B;--fw-surface: #1D2029;--fw-primary: #FFC145;--fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);--fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);--fw-secondary: #6B54A3;--fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);--fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 16%, transparent);--fw-success: #55D194;--fw-success-bg: color-mix(in srgb, var(--fw-success) 14%, transparent);--fw-warning: #FFD166;--fw-warning-bg: color-mix(in srgb, var(--fw-warning) 16%, transparent);--fw-danger: #FF8478;--fw-danger-bg: color-mix(in srgb, var(--fw-danger) 14%, transparent);--fw-info: #6BB3E8;--fw-info-bg: color-mix(in srgb, var(--fw-info) 14%, transparent);--fw-on-primary: #1F2430;--fw-on-secondary: #FFFFFF;--fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);--fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);--fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);--fw-overlay: rgba(0, 0, 0, .6);--fw-overlay-soft: rgba(0, 0, 0, .4);--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);--fw-shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);--fw-shadow-md: 0 4px 12px rgba(0, 0, 0, .35);--fw-shadow-lg: 0 12px 32px rgba(0, 0, 0, .45);--fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 22%, transparent);--fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 22%, transparent)}}.fw-root{background:var(--fw-bg);color:var(--fw-text);font-family:var(--fw-font-body);line-height:1.5;-webkit-font-smoothing:antialiased;transition:background var(--fw-motion-base) var(--fw-motion-ease),color var(--fw-motion-base) var(--fw-motion-ease)}.fw-root,.fw-root *,.fw-root *:before,.fw-root *:after{box-sizing:border-box}.fw-root :where(h1,h2,h3,h4){font-family:var(--fw-font-display);color:var(--fw-text);margin:0}.fw-root :where(p){margin:0}.fw-root :where(a){color:inherit}.fw-root :where(code){font-family:var(--fw-font-mono)}[hidden]{display:none!important}.fw-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.fw-scroll-lock{overflow:hidden}@media(prefers-reduced-motion:reduce){.fw-root{scroll-behavior:auto}.fw-btn,.fw-btn:hover,.fw-list-row,.fw-list-row:hover{transform:none}}.fw-wrap{max-width:1100px;margin:0 auto;padding:0 var(--fw-sp-5)}.fw-row{display:flex;gap:var(--fw-sp-4);flex-wrap:wrap;align-items:center}.fw-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--fw-sp-5)}@media(max-width:640px){.fw-grid-2{grid-template-columns:1fr}}.fw-btn{font-family:var(--fw-font-body);font-weight:700;font-size:15px;line-height:1.2;border-radius:var(--fw-r-md);padding:12px 22px;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:var(--fw-sp-2);text-decoration:none;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease),background var(--fw-motion-fast) var(--fw-motion-ease),border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-btn:hover{transform:translateY(-1px)}.fw-btn:active{transform:translateY(0)}.fw-btn:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-btn-primary{background:var(--fw-primary);color:var(--fw-on-primary);box-shadow:var(--fw-shadow-primary)}.fw-btn-primary:hover{background:var(--fw-primary-hover)}.fw-btn-secondary{background:var(--fw-secondary);color:var(--fw-on-secondary)}.fw-btn-secondary:hover{background:var(--fw-secondary-hover)}.fw-btn-ghost{background:transparent;color:var(--fw-text);border:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-btn-ghost:hover{border-color:var(--fw-text-soft)}.fw-btn-danger{background:var(--fw-danger-bg);color:var(--fw-danger)}.fw-btn-lg{padding:14px 26px}.fw-btn:disabled,.fw-btn[aria-disabled=true]{opacity:.45;cursor:not-allowed;transform:none}.fw-btn-loading{cursor:progress}.fw-btn .fw-spinner{margin-right:2px}.fw-icon-btn{width:32px;height:32px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;color:var(--fw-text-soft);flex-shrink:0;padding:0;text-decoration:none;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease),color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-icon-btn:hover{border-color:var(--fw-secondary);color:var(--fw-secondary)}.fw-icon-btn:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-icon-btn svg{width:15px;height:15px}.fw-card{background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-sm);padding:var(--fw-sp-5);color:var(--fw-text)}.fw-tag{display:inline-flex;align-items:center;gap:6px;font-family:var(--fw-font-mono);font-size:12px;font-weight:600;line-height:1.3;padding:5px 12px;border-radius:var(--fw-r-md);transform:rotate(-2deg);background:var(--fw-bg-dim);color:var(--fw-text-soft);white-space:nowrap}.fw-tag:nth-of-type(2n){transform:rotate(1.5deg)}.fw-tag:nth-of-type(3n){transform:rotate(-1deg)}.fw-tag-pill,.fw-tag-pill:nth-of-type(n){transform:none;font-size:11px;padding:4px 10px;border-radius:var(--fw-r-full)}.fw-tag-live{background:var(--fw-success-bg);color:var(--fw-success)}.fw-tag-live:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--fw-success)}.fw-tag-pending{background:var(--fw-warning-bg);color:var(--fw-warning)}.fw-tag-error{background:var(--fw-danger-bg);color:var(--fw-danger)}.fw-tag-info{background:var(--fw-info-bg);color:var(--fw-info)}.fw-tag-secondary{background:var(--fw-secondary-bg);color:var(--fw-secondary)}@media(prefers-reduced-motion:no-preference){.fw-tag{transition:transform var(--fw-motion-fast) var(--fw-motion-ease)}}.fw-eyebrow{display:inline-flex;align-items:center;gap:var(--fw-sp-2);font-family:var(--fw-font-mono);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fw-secondary);background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);padding:7px 16px;border-radius:var(--fw-r-full);box-shadow:var(--fw-shadow-sm)}.fw-eyebrow:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--fw-primary)}[data-theme=dark] .fw-eyebrow{color:var(--fw-secondary-hover)}.fw-field{display:flex;flex-direction:column;gap:6px;max-width:320px}.fw-field-full{max-width:none}.fw-label,.fw-field>label{font-size:13px;font-weight:600;color:var(--fw-text)}.fw-hint{font-size:12px;color:var(--fw-text-soft)}.fw-error-msg{font-size:12px;color:var(--fw-danger);font-weight:600}.fw-required{color:var(--fw-danger);font-weight:700;margin-left:3px}.fw-input,.fw-field input:not([type=checkbox]):not([type=radio]),.fw-field select,.fw-field textarea{font-family:var(--fw-font-body);font-size:15px;line-height:1.4;padding:11px 14px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);color:var(--fw-text);outline:none;width:100%;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease),background var(--fw-motion-base) var(--fw-motion-ease),color var(--fw-motion-base) var(--fw-motion-ease)}textarea.fw-input,.fw-field textarea{min-height:96px;resize:vertical}.fw-input::placeholder,.fw-field input::placeholder,.fw-field textarea::placeholder{color:var(--fw-text-soft);opacity:1}.fw-input:focus,.fw-field input:focus,.fw-field select:focus,.fw-field textarea:focus{border-color:var(--fw-primary-hover);box-shadow:var(--fw-focus-ring)}.fw-input.is-error,.fw-input[aria-invalid=true],.fw-field.is-error input,.fw-field.is-error select,.fw-field.is-error textarea,.fw-field input.is-error,.fw-field textarea.is-error{border-color:var(--fw-danger)}.fw-input:disabled,.fw-field input:disabled,.fw-field select:disabled,.fw-field textarea:disabled{background:var(--fw-bg-dim);color:var(--fw-text-soft);border-color:var(--fw-bg-dim);cursor:not-allowed}.fw-field.is-disabled .fw-label,.fw-field.is-disabled>label{color:var(--fw-text-soft)}.fw-checkbox,.fw-radio,.fw-toggle{position:relative;display:inline-flex;align-items:center;gap:10px;cursor:pointer;font-family:var(--fw-font-body);font-size:14px;font-weight:600;color:var(--fw-text)}.fw-checkbox input,.fw-radio input,.fw-toggle input{position:absolute;opacity:0;width:0;height:0;margin:0}.fw-checkbox:has(input:disabled),.fw-radio:has(input:disabled),.fw-toggle:has(input:disabled){cursor:not-allowed}.fw-checkbox input:disabled~span,.fw-radio input:disabled~span,.fw-toggle input:disabled~span{color:var(--fw-text-soft)}.fw-option-group{display:flex;flex-direction:column;gap:var(--fw-sp-3)}.fw-option-group-inline{flex-direction:row;flex-wrap:wrap;gap:var(--fw-sp-5)}.fw-checkbox .fw-box{width:20px;height:20px;border-radius:6px;border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--fw-motion-fast) var(--fw-motion-ease),border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-checkbox .fw-box:after{content:"";width:12px;height:12px;opacity:0;background-color:var(--fw-on-primary);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:opacity .1s var(--fw-motion-ease)}.fw-checkbox input:checked+.fw-box{background:var(--fw-primary);border-color:var(--fw-primary)}.fw-checkbox input:checked+.fw-box:after{opacity:1}.fw-checkbox input:indeterminate+.fw-box{background:var(--fw-primary);border-color:var(--fw-primary)}.fw-checkbox input:indeterminate+.fw-box:after{opacity:1;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8h9' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8h9' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat}.fw-checkbox input:focus-visible+.fw-box{box-shadow:var(--fw-focus-ring)}.fw-checkbox input:disabled+.fw-box{background:var(--fw-bg-dim);border-color:var(--fw-bg-dim)}.fw-radio .fw-box{width:20px;height:20px;border-radius:50%;border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-radio .fw-box:after{content:"";width:10px;height:10px;border-radius:50%;background:transparent;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-radio input:checked+.fw-box{border-color:var(--fw-primary)}.fw-radio input:checked+.fw-box:after{background:var(--fw-primary)}.fw-radio input:focus-visible+.fw-box{box-shadow:var(--fw-focus-ring)}.fw-radio input:disabled+.fw-box{background:var(--fw-bg-dim);border-color:var(--fw-bg-dim)}.fw-toggle .fw-track{width:42px;height:24px;border-radius:var(--fw-r-full);background:var(--fw-bg-dim);position:relative;flex-shrink:0;transition:background .16s var(--fw-motion-ease)}.fw-toggle .fw-thumb{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:var(--fw-surface);box-shadow:var(--fw-shadow-sm);transition:transform .16s var(--fw-motion-ease)}.fw-toggle input:checked+.fw-track{background:var(--fw-primary)}.fw-toggle input:checked+.fw-track .fw-thumb{transform:translate(18px)}.fw-toggle input:focus-visible+.fw-track{box-shadow:var(--fw-focus-ring)}.fw-toggle input:disabled+.fw-track{opacity:.5}.fw-combobox{position:relative}.fw-combobox-list{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-md);box-shadow:var(--fw-shadow-lg);max-height:220px;overflow-y:auto;padding:6px;margin:0;list-style:none;opacity:0;transform:translateY(-4px);pointer-events:none;transition:opacity .14s var(--fw-motion-ease),transform .14s var(--fw-motion-ease)}.fw-combobox-list.is-open{opacity:1;transform:translateY(0);pointer-events:auto}.fw-combobox-option{padding:10px 12px;border-radius:var(--fw-r-sm);font-family:var(--fw-font-body);font-size:14px;cursor:pointer;color:var(--fw-text)}.fw-combobox-option:hover,.fw-combobox-option.is-active{background:var(--fw-bg)}.fw-combobox-option b{color:var(--fw-primary-hover);font-weight:700}.fw-combobox-empty{padding:14px 12px;font-size:13px;color:var(--fw-text-soft);text-align:center}@media(prefers-reduced-motion:reduce){.fw-combobox-list{transform:none}}.fw-alert{display:flex;gap:var(--fw-sp-3);padding:var(--fw-sp-4);border-radius:var(--fw-r-md);align-items:flex-start;font-family:var(--fw-font-body);color:var(--fw-text);background:var(--fw-bg-dim)}.fw-alert-dot{width:20px;height:20px;border-radius:50%;flex-shrink:0;margin-top:2px;background:var(--fw-text-soft)}.fw-alert-title{font-weight:700;font-size:14px}.fw-alert-body{font-size:13px;color:var(--fw-text-soft);margin-top:2px}.fw-alert-success{background:var(--fw-success-bg)}.fw-alert-success .fw-alert-dot{background:var(--fw-success)}.fw-alert-error{background:var(--fw-danger-bg)}.fw-alert-error .fw-alert-dot{background:var(--fw-danger)}.fw-alert-pending{background:var(--fw-warning-bg)}.fw-alert-pending .fw-alert-dot{background:var(--fw-warning)}.fw-alert-info{background:var(--fw-info-bg)}.fw-alert-info .fw-alert-dot{background:var(--fw-info)}.fw-alert-with-action{align-items:center;justify-content:space-between;flex-wrap:wrap}.fw-alert-with-action .fw-alert-main{display:flex;align-items:center;gap:var(--fw-sp-3)}.fw-progress-label{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px;font-family:var(--fw-font-body);font-size:13px}.fw-progress-name{font-weight:600;color:var(--fw-text)}.fw-progress-pct{font-family:var(--fw-font-mono);color:var(--fw-text-soft)}.fw-progress{position:relative;height:10px;border-radius:var(--fw-r-full);background:var(--fw-bg-dim);overflow:hidden}.fw-progress-sm{height:8px}.fw-progress-fill{height:100%;border-radius:var(--fw-r-full);background:var(--fw-primary);transition:width .4s var(--fw-motion-ease)}.fw-progress.is-success .fw-progress-fill,.fw-progress-fill.is-success{background:var(--fw-success)}.fw-progress.is-indeterminate .fw-progress-fill{position:absolute;width:40%;left:-40%;animation:fw-indeterminate-slide 1.4s ease-in-out infinite}@keyframes fw-indeterminate-slide{0%{left:-40%;width:40%}50%{width:60%}to{left:100%;width:40%}}@media(prefers-reduced-motion:reduce){.fw-progress.is-indeterminate .fw-progress-fill{position:static;width:100%;animation:fw-pulse-opacity 1.2s ease-in-out infinite}}.fw-spinner{display:inline-block;border-radius:50%;flex-shrink:0;width:24px;height:24px;border:3px solid var(--fw-bg-dim);border-top-color:currentColor;animation:fw-spin .8s linear infinite}.fw-spinner-sm{width:16px;height:16px;border-width:2px}.fw-spinner-md{width:24px;height:24px;border-width:3px}.fw-spinner-lg{width:40px;height:40px;border-width:4px}@keyframes fw-spin{to{transform:rotate(360deg)}}@keyframes fw-pulse-opacity{0%,to{opacity:1}50%{opacity:.35}}@media(prefers-reduced-motion:reduce){.fw-spinner{animation:fw-pulse-opacity 1.2s ease-in-out infinite;border-top-color:var(--fw-bg-dim)}}.fw-nav{position:relative;background:var(--fw-secondary);border-radius:var(--fw-r-lg);padding:var(--fw-sp-4) var(--fw-sp-5);display:flex;align-items:center;justify-content:space-between;gap:var(--fw-sp-4);box-shadow:var(--fw-shadow-md);font-family:var(--fw-font-body);color:var(--fw-on-secondary)}.fw-nav-sticky{position:sticky;top:var(--fw-sp-5);z-index:100}.fw-nav-brand{color:var(--fw-on-secondary);font-family:var(--fw-font-display);font-weight:800;font-size:18px;display:flex;align-items:center;gap:var(--fw-sp-2);text-decoration:none}.fw-nav-dot{width:10px;height:10px;border-radius:50%;background:var(--fw-primary)}.fw-nav-hex{width:16px;height:16px;background:var(--fw-primary);clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%)}.fw-nav-links{display:flex;gap:var(--fw-sp-5);align-items:center}.fw-nav-links a{color:var(--fw-on-secondary-soft);font-size:14px;font-weight:600;text-decoration:none;transition:color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-links a:hover{color:var(--fw-on-secondary)}.fw-nav-links a.is-active{color:var(--fw-on-secondary);border-bottom:2px solid var(--fw-primary);padding-bottom:3px}.fw-nav-right{display:flex;align-items:center;gap:var(--fw-sp-4)}.fw-nav-avatar{width:34px;height:34px;border-radius:var(--fw-r-sm);background:var(--fw-primary);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;color:var(--fw-on-primary);font-family:var(--fw-font-display);border:none;padding:0;cursor:default}.fw-nav-btn,.fw-nav-toggle{width:38px;height:38px;border-radius:var(--fw-r-sm);background:var(--fw-on-secondary-fill);border:var(--fw-border-w) solid var(--fw-on-secondary-line);color:var(--fw-on-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;font-size:15px;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-btn:hover,.fw-nav-toggle:hover{background:var(--fw-on-secondary-line)}.fw-nav-btn:focus-visible,.fw-nav-toggle:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-nav-toggle{display:none;flex-direction:column;gap:4px}.fw-nav-toggle span{width:16px;height:2px;background:var(--fw-on-secondary);border-radius:2px;transition:transform var(--fw-motion-base) var(--fw-motion-ease),opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-nav-toggle[aria-expanded=true] span:nth-child(1){transform:translateY(6px) rotate(45deg)}.fw-nav-toggle[aria-expanded=true] span:nth-child(2){opacity:0}.fw-nav-toggle[aria-expanded=true] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}.fw-nav-dropdown{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:20;background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-lg);padding:var(--fw-sp-3);display:flex;flex-direction:column;gap:2px;opacity:0;transform:translateY(-6px) scale(.98);pointer-events:none;transition:opacity .16s var(--fw-motion-ease),transform .16s var(--fw-motion-ease)}.fw-nav-dropdown.is-open{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.fw-nav-dropdown-menu{left:auto;min-width:200px}.fw-nav-dropdown a,.fw-nav-dropdown button{color:var(--fw-text);font-family:var(--fw-font-body);font-size:15px;font-weight:600;text-decoration:none;text-align:left;padding:12px 14px;border-radius:var(--fw-r-sm);background:none;border:none;cursor:pointer;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-dropdown a:hover,.fw-nav-dropdown button:hover{background:var(--fw-bg)}.fw-nav-dropdown a.is-active{background:var(--fw-primary);color:var(--fw-on-primary)}@media(max-width:600px){.fw-nav-links{display:none}.fw-nav-toggle{display:flex}}@media(prefers-reduced-motion:reduce){.fw-nav-dropdown{transform:none}}.fw-stat-label{font-family:var(--fw-font-body);font-size:13px;color:var(--fw-text-soft);font-weight:600}.fw-stat-value{font-family:var(--fw-font-display);font-size:32px;font-weight:800;line-height:1.1;color:var(--fw-text);margin-top:4px}.fw-stat-value .fw-stat-unit{font-size:18px;color:var(--fw-primary-hover)}.fw-stat-delta{font-family:var(--fw-font-mono);font-size:12px;font-weight:600;color:var(--fw-text-soft);margin-top:4px}.fw-stat-delta.is-up{color:var(--fw-success)}.fw-stat-delta.is-down{color:var(--fw-danger)}.fw-empty{text-align:center;padding:var(--fw-sp-7) var(--fw-sp-5);font-family:var(--fw-font-body)}.fw-empty-blob{width:72px;height:72px;margin:0 auto var(--fw-sp-4);border-radius:38% 62% 60% 40%/48% 42% 58% 52%;background:linear-gradient(135deg,var(--fw-primary),var(--fw-primary-soft));display:flex;align-items:center;justify-content:center;font-size:28px}.fw-empty-title{font-family:var(--fw-font-display);font-size:17px;font-weight:700;color:var(--fw-text);margin:0 0 6px}.fw-empty-body{font-size:14px;color:var(--fw-text-soft);max-width:36ch;margin:0 auto var(--fw-sp-4)}.fw-modal-overlay{position:fixed;inset:0;background:var(--fw-overlay);display:flex;align-items:center;justify-content:center;padding:var(--fw-sp-5);z-index:100;opacity:0;pointer-events:none;transition:opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-modal-overlay.is-open{opacity:1;pointer-events:auto}.fw-modal{background:var(--fw-surface);color:var(--fw-text);font-family:var(--fw-font-body);border-radius:var(--fw-r-xl);box-shadow:var(--fw-shadow-lg);width:100%;max-width:460px;max-height:88vh;overflow-y:auto;padding:var(--fw-sp-6);transform:translateY(8px) scale(.98);transition:transform var(--fw-motion-base) var(--fw-motion-ease)}.fw-modal-wide{max-width:600px}.fw-modal-overlay.is-open .fw-modal{transform:translateY(0) scale(1)}.fw-modal-head{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--fw-sp-3);margin-bottom:var(--fw-sp-5)}.fw-modal-head h2,.fw-modal-title{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);margin:0}.fw-modal-sub{font-size:13px;color:var(--fw-text-soft);margin:2px 0 0}.fw-modal-foot{display:flex;justify-content:flex-end;gap:var(--fw-sp-3);align-items:center;margin-top:var(--fw-sp-2);padding-top:var(--fw-sp-5);border-top:var(--fw-border-w) solid var(--fw-bg-dim)}@media(prefers-reduced-motion:reduce){.fw-modal{transform:none}}.fw-drawer-overlay{position:fixed;inset:0;background:var(--fw-overlay-soft);opacity:0;pointer-events:none;transition:opacity var(--fw-motion-base) var(--fw-motion-ease);z-index:90}.fw-drawer-overlay.is-open{opacity:1;pointer-events:auto}.fw-drawer{position:fixed;top:0;right:0;height:100%;width:440px;max-width:92vw;background:var(--fw-bg);color:var(--fw-text);font-family:var(--fw-font-body);box-shadow:var(--fw-shadow-lg);border-left:var(--fw-border-w) solid var(--fw-bg-dim);transform:translate(100%);transition:transform .24s var(--fw-motion-ease);z-index:91;display:flex;flex-direction:column}.fw-drawer.is-open{transform:translate(0)}.fw-drawer-head{padding:var(--fw-sp-5);border-bottom:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:flex-start;gap:var(--fw-sp-3);flex-shrink:0}.fw-drawer-head-text{flex:1;min-width:0}.fw-drawer-eyebrow{font-family:var(--fw-font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--fw-text-soft);margin-bottom:4px}.fw-drawer-title{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);margin:0}.fw-drawer-title-input{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);border:none;background:transparent;padding:2px 0;width:100%;outline:none;border-radius:6px}.fw-drawer-title-input:focus{background:var(--fw-bg);padding:2px 6px;margin:0 -6px}.fw-drawer>form{flex:1;min-height:0;display:flex;flex-direction:column}.fw-drawer-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:var(--fw-sp-5);display:flex;flex-direction:column;gap:var(--fw-sp-5)}.fw-drawer-foot{padding:var(--fw-sp-4) var(--fw-sp-5);display:flex;align-items:center;justify-content:space-between;gap:var(--fw-sp-3);flex-shrink:0;border-top:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface)}@media(max-width:560px){.fw-drawer{width:100vw;max-width:100vw}}@media(prefers-reduced-motion:reduce){.fw-drawer{transition:opacity var(--fw-motion-base) var(--fw-motion-ease);transform:none;opacity:0;pointer-events:none}.fw-drawer.is-open{opacity:1;pointer-events:auto}}.fw-toast{position:fixed;bottom:var(--fw-sp-6);right:var(--fw-sp-6);z-index:200;display:flex;align-items:center;gap:var(--fw-sp-3);max-width:min(360px,calc(100vw - 2 * var(--fw-sp-5)));background:var(--fw-success-bg);color:var(--fw-text);font-family:var(--fw-font-body);border-radius:var(--fw-r-md);padding:var(--fw-sp-3) var(--fw-sp-4);box-shadow:var(--fw-shadow-lg);font-size:13px;font-weight:600;transform:translateY(12px);opacity:0;pointer-events:none;transition:transform var(--fw-motion-base) var(--fw-motion-ease),opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-toast.is-show{transform:translateY(0);opacity:1;pointer-events:auto}.fw-toast-dot{width:8px;height:8px;border-radius:50%;background:var(--fw-success);flex-shrink:0}.fw-toast-error{background:var(--fw-danger-bg)}.fw-toast-error .fw-toast-dot{background:var(--fw-danger)}.fw-toast-info{background:var(--fw-info-bg)}.fw-toast-info .fw-toast-dot{background:var(--fw-info)}.fw-toast-pending{background:var(--fw-warning-bg)}.fw-toast-pending .fw-toast-dot{background:var(--fw-warning)}@media(prefers-reduced-motion:reduce){.fw-toast{transform:none}}.fw-list-row{display:block;background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-sm);padding:var(--fw-sp-4) var(--fw-sp-5);color:inherit;font-family:var(--fw-font-body);text-decoration:none;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease)}.fw-list-row:hover{transform:translateY(-1px);box-shadow:var(--fw-shadow-md);text-decoration:none}.fw-list-row:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-list-row.is-locked{opacity:.6}.fw-list-row.is-locked:hover{transform:none;box-shadow:var(--fw-shadow-sm)}.fw-list-row+.fw-list-row{margin-top:var(--fw-sp-3)}.fw-list-row-main{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fw-sp-2) var(--fw-sp-4)}.fw-list-row-title{font-family:var(--fw-font-display);font-weight:700;font-size:16px;color:var(--fw-text)}.fw-list-row-meta{font-size:13px;color:var(--fw-text-soft)}.fw-sub-list{margin:var(--fw-sp-2) 0 0 var(--fw-sp-5);padding-left:var(--fw-sp-4);border-left:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-sub-list-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fw-sp-2) var(--fw-sp-3);padding:var(--fw-sp-2) 0}.fw-sub-list-row+.fw-sub-list-row{border-top:1px solid var(--fw-bg-dim)}.fw-sub-list-title{font-size:13.5px;font-weight:600;color:var(--fw-text)}.fw-disclosure>summary{cursor:pointer;color:var(--fw-secondary);font-family:var(--fw-font-body);font-weight:600;font-size:13px;list-style:none;display:flex;align-items:center;gap:6px}.fw-disclosure>summary::-webkit-details-marker{display:none}.fw-disclosure>summary:hover{text-decoration:underline}.fw-disclosure>summary:focus-visible{outline:none;border-radius:4px;box-shadow:var(--fw-focus-ring)}.fw-disclosure-chevron{width:12px;height:12px;flex-shrink:0;transition:transform .15s var(--fw-motion-ease)}.fw-disclosure[open]>summary .fw-disclosure-chevron{transform:rotate(180deg)}.fw-disclosure-count{font-family:var(--fw-font-mono);font-size:10.5px;font-weight:700;color:var(--fw-secondary);background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-full);padding:1px 7px}.fw-disclosure-body{margin-top:var(--fw-sp-3);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-md);padding:var(--fw-sp-4);background:var(--fw-bg);display:flex;flex-direction:column;gap:var(--fw-sp-3)}.fw-menu{--fw-menu-indent: var(--fw-sp-4);--fw-menu-row-h: 36px;font-family:var(--fw-font-body);color:var(--fw-text)}.fw-menu-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.fw-menu-group>.fw-menu-list{margin:2px 0 0 var(--fw-menu-indent);padding-left:var(--fw-sp-3);border-left:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-menu-link,.fw-menu-summary{display:flex;align-items:center;gap:var(--fw-sp-2);min-height:var(--fw-menu-row-h);padding:0 var(--fw-sp-3);border-radius:var(--fw-r-sm);color:var(--fw-text);font-family:var(--fw-font-body);font-size:14px;font-weight:600;line-height:1.3;text-decoration:none;text-align:left;background:none;border:none;cursor:pointer;transition:background-color var(--fw-motion-fast) var(--fw-motion-ease),color var(--fw-motion-fast) var(--fw-motion-ease)}@media(hover:hover){.fw-menu-link:hover,.fw-menu-summary:hover{background:var(--fw-bg);text-decoration:none}}.fw-menu-link:focus-visible,.fw-menu-summary:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-menu-link[aria-current=page]{background:var(--fw-secondary-bg);color:var(--fw-secondary)}.fw-menu-summary.is-current{color:var(--fw-secondary)}.fw-menu-summary{list-style:none;user-select:none}.fw-menu-summary::-webkit-details-marker{display:none}.fw-menu-summary:after{content:"";flex-shrink:0;width:16px;height:16px;margin-left:auto;background-color:currentColor;opacity:.55;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M6 4l4 4-4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M6 4l4 4-4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),opacity var(--fw-motion-fast) var(--fw-motion-ease)}.fw-menu-summary:hover:after,.fw-menu-summary.is-current:after{opacity:1}.fw-menu-group[open]>.fw-menu-summary:after{transform:rotate(90deg)}.fw-menu-split{position:relative}.fw-menu-split>.fw-menu-link{padding-right:44px}.fw-menu-summary-icon{position:absolute;top:0;right:0;width:var(--fw-menu-row-h);height:var(--fw-menu-row-h);min-height:0;padding:0;justify-content:center}.fw-menu-summary-icon:after{margin-left:0}.fw-menu-panel{padding:var(--fw-sp-2) var(--fw-sp-3) var(--fw-sp-4);color:var(--fw-text-soft);font-size:14px;line-height:1.5}.fw-menu-panel>:first-child{margin-top:0}.fw-menu-panel>:last-child{margin-bottom:0}.fw-menu-accordion>.fw-menu-group+.fw-menu-group{border-top:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary{min-height:44px;padding-inline:0;border-radius:0;font-family:var(--fw-font-display);font-size:15px;font-weight:700}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}.fw-menu-accordion>.fw-menu-group[open]>.fw-menu-summary:after{transform:rotate(180deg)}@media(hover:hover){.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:hover{background:none;color:var(--fw-secondary)}}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:focus-visible{border-radius:4px}.fw-menu-accordion>.fw-menu-group>.fw-menu-panel{padding-inline:0}@media(prefers-reduced-motion:reduce){.fw-menu-summary:after{transition:none}}.fw-pagination{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--fw-sp-3);font-family:var(--fw-font-body)}.fw-pag-info,.fw-pag-label{font-family:var(--fw-font-mono);font-size:12px;color:var(--fw-text-soft)}.fw-pag-controls{display:flex;align-items:center;gap:var(--fw-sp-3)}.fw-btn-page{display:inline-flex;align-items:center;height:34px;padding:0 14px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);color:var(--fw-text);font-family:var(--fw-font-body);font-size:13px;font-weight:600;text-decoration:none;cursor:pointer;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-btn-page:hover{border-color:var(--fw-text-soft);text-decoration:none}.fw-btn-page:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-btn-page.is-disabled,.fw-btn-page[aria-disabled=true],.fw-btn-page:disabled{opacity:.35;cursor:not-allowed;pointer-events:none}.fw-table-wrap{overflow-x:auto;background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-lg);box-shadow:var(--fw-shadow-sm);font-family:var(--fw-font-body);color:var(--fw-text)}.fw-table-wrap:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-table-wrap.fw-table-sticky{max-height:var(--fw-table-max-height, 460px);overflow:auto}.fw-table-sticky .fw-table thead th{position:sticky;top:0;z-index:1}.fw-table{width:100%;border-collapse:separate;border-spacing:0;font-family:var(--fw-font-body);font-size:14px;line-height:1.4;color:var(--fw-text);text-align:left}.fw-table caption{caption-side:top;text-align:left;font-family:var(--fw-font-display);font-weight:700;font-size:16px;color:var(--fw-text);padding:var(--fw-sp-4) var(--fw-sp-5) var(--fw-sp-2)}.fw-table th,.fw-table td{padding:var(--fw-sp-3) var(--fw-sp-4);vertical-align:middle}.fw-table th:first-child,.fw-table td:first-child{padding-left:var(--fw-sp-5)}.fw-table th:last-child,.fw-table td:last-child{padding-right:var(--fw-sp-5)}.fw-table thead th{font-size:12px;font-weight:700;letter-spacing:.02em;color:var(--fw-text-soft);background:var(--fw-surface);border-bottom:var(--fw-border-w) solid var(--fw-bg-dim);white-space:nowrap}.fw-table tbody tr+tr>td{border-top:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-table tbody td{transition:background-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-table-striped tbody tr:nth-child(2n)>td{background:var(--fw-bg)}@media(hover:hover){.fw-table tbody tr:hover>td{background:var(--fw-secondary-bg)}}.fw-table tbody tr.is-selected>td,.fw-table tbody tr[aria-selected=true]>td{background:var(--fw-secondary-bg)}.fw-table tbody tr.is-selected>td:first-child,.fw-table tbody tr[aria-selected=true]>td:first-child{box-shadow:inset 3px 0 0 var(--fw-secondary)}.fw-table-compact th,.fw-table-compact td{padding:var(--fw-sp-2) var(--fw-sp-3);font-size:13px}.fw-table-compact th:first-child,.fw-table-compact td:first-child{padding-left:var(--fw-sp-4)}.fw-table-compact th:last-child,.fw-table-compact td:last-child{padding-right:var(--fw-sp-4)}.fw-table-num{font-family:var(--fw-font-mono);text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}.fw-table-num .fw-table-sort{flex-direction:row-reverse}.fw-table-select{width:1%;padding-right:0}.fw-table-select .fw-checkbox{gap:0;vertical-align:middle}.fw-table-actions{width:1%;text-align:right;white-space:nowrap}.fw-table-actions .fw-icon-btn{vertical-align:middle}.fw-table-actions>*+*{margin-left:var(--fw-sp-1)}.fw-table-empty>td{text-align:center;padding:var(--fw-sp-7) var(--fw-sp-5);color:var(--fw-text-soft);font-family:var(--fw-font-display)}.fw-table-empty:hover>td{background:transparent}.fw-table-loading>td{text-align:center;padding:var(--fw-sp-6) var(--fw-sp-5)}.fw-table[aria-busy=true] tbody,.fw-table.is-loading tbody{opacity:.5;pointer-events:none;transition:opacity var(--fw-motion-fast) var(--fw-motion-ease)}th[data-fw-sort]{cursor:pointer}.fw-table-sort{display:inline-flex;align-items:center;gap:var(--fw-sp-1);padding:2px 4px;margin:-2px -4px;border:0;background:none;font:inherit;color:inherit;letter-spacing:inherit;cursor:pointer;border-radius:6px}th[data-fw-sort]:hover .fw-table-sort,th[aria-sort=ascending] .fw-table-sort,th[aria-sort=descending] .fw-table-sort{color:var(--fw-text)}.fw-table-sort:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-table-sort:after{content:"";width:12px;height:12px;flex-shrink:0;background-color:currentColor;opacity:.35;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M5 6.5l3-3 3 3M5 9.5l3 3 3-3' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M5 6.5l3-3 3 3M5 9.5l3 3 3-3' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:opacity var(--fw-motion-fast) var(--fw-motion-ease)}th[aria-sort=ascending] .fw-table-sort:after{opacity:1;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 10l4-4 4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 10l4-4 4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}th[aria-sort=descending] .fw-table-sort:after{opacity:1;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
|
|
1
|
+
/*! fernwell v0.4.0 | MIT | https://github.com/JacobKnaack/fernwell */
|
|
2
|
+
@layer fw-tokens{:root,[data-theme=light]{--fw-text: #1F2430;--fw-text-soft: #565D6E;--fw-bg: #F5F6F1;--fw-bg-dim: #EAEBE4;--fw-surface: #FFFFFF;--fw-primary: #FFC145;--fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);--fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);--fw-secondary: #4C3A73;--fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);--fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 10%, var(--fw-surface));--fw-success: #3FA672;--fw-success-bg: color-mix(in srgb, var(--fw-success) 12%, var(--fw-surface));--fw-warning: #E8A521;--fw-warning-bg: color-mix(in srgb, var(--fw-warning) 14%, var(--fw-surface));--fw-danger: #E85B4F;--fw-danger-bg: color-mix(in srgb, var(--fw-danger) 13%, var(--fw-surface));--fw-info: #3E8FD0;--fw-info-bg: color-mix(in srgb, var(--fw-info) 12%, var(--fw-surface));--fw-on-primary: #1F2430;--fw-on-secondary: #FFFFFF;--fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);--fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);--fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);--fw-overlay: rgba(31, 36, 48, .55);--fw-overlay-soft: rgba(31, 36, 48, .32);--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);--fw-scrollbar-thumb: var(--fw-text-soft);--fw-scrollbar-thumb-hover: color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%);--fw-scrollbar-track: transparent;--fw-font-display: "Plus Jakarta Sans", system-ui, sans-serif;--fw-font-body: "Inter", system-ui, sans-serif;--fw-font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--fw-sp-1: 4px;--fw-sp-2: 8px;--fw-sp-3: 12px;--fw-sp-4: 16px;--fw-sp-5: 24px;--fw-sp-6: 32px;--fw-sp-7: 48px;--fw-sp-8: 64px;--fw-sp-9: 96px;--fw-r-sm: 10px;--fw-r-md: 16px;--fw-r-lg: 24px;--fw-r-xl: 32px;--fw-r-full: 999px;--fw-shadow-sm: 0 1px 2px rgba(31, 36, 48, .06), 0 1px 1px rgba(31, 36, 48, .04);--fw-shadow-md: 0 4px 12px rgba(31, 36, 48, .08), 0 2px 4px rgba(31, 36, 48, .04);--fw-shadow-lg: 0 12px 32px rgba(31, 36, 48, .12), 0 4px 8px rgba(31, 36, 48, .06);--fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 35%, transparent);--fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 28%, transparent);--fw-border-w: 1.5px;--fw-motion-fast: .12s;--fw-motion-base: .18s;--fw-motion-ease: ease}[data-theme=dark]{--fw-text: #F2F1EA;--fw-text-soft: #9CA1B0;--fw-bg: #14161C;--fw-bg-dim: #2B2F3B;--fw-surface: #1D2029;--fw-primary: #FFC145;--fw-primary-hover: color-mix(in srgb, var(--fw-primary), var(--fw-text) 12%);--fw-primary-soft: color-mix(in srgb, var(--fw-primary), white 35%);--fw-secondary: #6B54A3;--fw-secondary-hover: color-mix(in srgb, var(--fw-secondary), var(--fw-text) 15%);--fw-secondary-bg: color-mix(in srgb, var(--fw-secondary) 16%, transparent);--fw-success: #55D194;--fw-success-bg: color-mix(in srgb, var(--fw-success) 14%, transparent);--fw-warning: #FFD166;--fw-warning-bg: color-mix(in srgb, var(--fw-warning) 16%, transparent);--fw-danger: #FF8478;--fw-danger-bg: color-mix(in srgb, var(--fw-danger) 14%, transparent);--fw-info: #6BB3E8;--fw-info-bg: color-mix(in srgb, var(--fw-info) 14%, transparent);--fw-on-primary: #1F2430;--fw-on-secondary: #FFFFFF;--fw-on-secondary-soft: color-mix(in srgb, var(--fw-on-secondary) 72%, transparent);--fw-on-secondary-fill: color-mix(in srgb, var(--fw-on-secondary) 10%, transparent);--fw-on-secondary-line: color-mix(in srgb, var(--fw-on-secondary) 16%, transparent);--fw-overlay: rgba(0, 0, 0, .6);--fw-overlay-soft: rgba(0, 0, 0, .4);--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);--fw-scrollbar-thumb: var(--fw-text-soft);--fw-scrollbar-thumb-hover: color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%);--fw-scrollbar-track: transparent;--fw-shadow-sm: 0 1px 2px rgba(0, 0, 0, .3);--fw-shadow-md: 0 4px 12px rgba(0, 0, 0, .35);--fw-shadow-lg: 0 12px 32px rgba(0, 0, 0, .45);--fw-shadow-primary: 0 6px 16px color-mix(in srgb, var(--fw-primary) 22%, transparent);--fw-shadow-success: 0 6px 16px color-mix(in srgb, var(--fw-success) 22%, transparent)}}.fw-root{background:var(--fw-bg);color:var(--fw-text);font-family:var(--fw-font-body);line-height:1.5;-webkit-font-smoothing:antialiased;transition:background var(--fw-motion-base) var(--fw-motion-ease),color var(--fw-motion-base) var(--fw-motion-ease)}[data-fw-theme-init],[data-fw-theme-init] *{transition:none!important}.fw-root,.fw-root *,.fw-root *:before,.fw-root *:after{box-sizing:border-box}.fw-root :where(h1,h2,h3,h4){font-family:var(--fw-font-display);color:var(--fw-text);margin:0}.fw-root :where(p){margin:0}.fw-root :where(a){color:inherit}.fw-root :where(code){font-family:var(--fw-font-mono)}[hidden]{display:none!important}.fw-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}html:has(body.fw-scroll-lock){scrollbar-gutter:stable}.fw-scroll-lock{overflow:hidden}@media(prefers-reduced-motion:reduce){.fw-root{scroll-behavior:auto}.fw-btn,.fw-btn:hover,.fw-list-row,.fw-list-row:hover{transform:none}}.fw-wrap{max-width:1100px;margin:0 auto;padding:0 var(--fw-sp-5)}.fw-row{display:flex;gap:var(--fw-sp-4);flex-wrap:wrap;align-items:center}.fw-grid-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--fw-sp-5)}@media(max-width:640px){.fw-grid-2{grid-template-columns:1fr}}.fw-spacer{display:block;flex-shrink:0}.fw-spacer[data-fw-axis=horizontal]{display:inline-block;width:var(--fw-spacer-size, var(--fw-sp-4));height:1px}.fw-spacer:not([data-fw-axis=horizontal]):not([data-fw-axis=both]){width:100%;height:var(--fw-spacer-size, var(--fw-sp-4))}.fw-spacer[data-fw-axis=both]{width:var(--fw-spacer-size, var(--fw-sp-4));height:var(--fw-spacer-size, var(--fw-sp-4))}.fw-spacer[data-fw-size="1"]{--fw-spacer-size: var(--fw-sp-1)}.fw-spacer[data-fw-size="2"]{--fw-spacer-size: var(--fw-sp-2)}.fw-spacer[data-fw-size="3"]{--fw-spacer-size: var(--fw-sp-3)}.fw-spacer[data-fw-size="4"]{--fw-spacer-size: var(--fw-sp-4)}.fw-spacer[data-fw-size="5"]{--fw-spacer-size: var(--fw-sp-5)}.fw-spacer[data-fw-size="6"]{--fw-spacer-size: var(--fw-sp-6)}.fw-spacer[data-fw-size="7"]{--fw-spacer-size: var(--fw-sp-7)}.fw-spacer[data-fw-size="8"]{--fw-spacer-size: var(--fw-sp-8)}.fw-spacer[data-fw-size="9"]{--fw-spacer-size: var(--fw-sp-9)}.fw-spacer[data-fw-size=auto]{flex:1 1 auto;width:auto;height:auto}.fw-divider{border:none;margin:0;flex-shrink:0;background:var(--fw-bg-dim)}.fw-divider,.fw-divider[aria-orientation=horizontal]{width:100%;height:var(--fw-border-w)}.fw-divider[aria-orientation=vertical]{width:var(--fw-border-w);height:100%;align-self:stretch}.fw-divider-dashed,.fw-divider-dotted{background:none;height:0}.fw-divider-dashed{border-top:var(--fw-border-w) dashed var(--fw-bg-dim)}.fw-divider-dotted{border-top:var(--fw-border-w) dotted var(--fw-bg-dim)}.fw-divider[aria-orientation=vertical].fw-divider-dashed,.fw-divider[aria-orientation=vertical].fw-divider-dotted{width:0;border-top:none}.fw-divider[aria-orientation=vertical].fw-divider-dashed{border-left:var(--fw-border-w) dashed var(--fw-bg-dim)}.fw-divider[aria-orientation=vertical].fw-divider-dotted{border-left:var(--fw-border-w) dotted var(--fw-bg-dim)}.fw-divider-labeled{display:flex;align-items:center;gap:var(--fw-sp-3);width:100%;color:var(--fw-text-soft);font-size:13px;font-family:var(--fw-font-body)}.fw-divider-labeled:before,.fw-divider-labeled:after{content:"";flex:1;height:var(--fw-border-w);background:var(--fw-bg-dim)}.fw-divider-labeled-start:before{flex:0 0 var(--fw-sp-5)}.fw-divider-labeled-end:after{flex:0 0 var(--fw-sp-5)}.fw-aspect-ratio{position:relative;overflow:hidden;width:100%;aspect-ratio:var(--fw-aspect-ratio, 16 / 9)}.fw-aspect-ratio>img,.fw-aspect-ratio>video,.fw-aspect-ratio>iframe,.fw-aspect-ratio>.fw-aspect-ratio-media{display:block;width:100%;height:100%;object-fit:cover;object-position:var(--fw-aspect-position, 50% 50%)}.fw-aspect-ratio[data-fw-ratio="1:1"]{--fw-aspect-ratio: 1 / 1}.fw-aspect-ratio[data-fw-ratio="4:3"]{--fw-aspect-ratio: 4 / 3}.fw-aspect-ratio[data-fw-ratio="16:9"]{--fw-aspect-ratio: 16 / 9}.fw-aspect-ratio[data-fw-ratio="21:9"]{--fw-aspect-ratio: 21 / 9}.fw-aspect-ratio[data-fw-fit=contain]>img,.fw-aspect-ratio[data-fw-fit=contain]>video,.fw-aspect-ratio[data-fw-fit=contain]>iframe,.fw-aspect-ratio[data-fw-fit=contain]>.fw-aspect-ratio-media{object-fit:contain}.fw-btn{font-family:var(--fw-font-body);font-weight:700;font-size:15px;line-height:1.2;border-radius:var(--fw-r-md);padding:12px 22px;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:var(--fw-sp-2);text-decoration:none;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease),background var(--fw-motion-fast) var(--fw-motion-ease),border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-btn:hover{transform:translateY(-1px)}.fw-btn:active{transform:translateY(0)}.fw-btn:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-btn-primary{background:var(--fw-primary);color:var(--fw-on-primary);box-shadow:var(--fw-shadow-primary)}.fw-btn-primary:hover{background:var(--fw-primary-hover)}.fw-btn-secondary{background:var(--fw-secondary);color:var(--fw-on-secondary)}.fw-btn-secondary:hover{background:var(--fw-secondary-hover)}.fw-btn-ghost{background:transparent;color:var(--fw-text);border:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-btn-ghost:hover{border-color:var(--fw-text-soft)}.fw-btn-danger{background:var(--fw-danger-bg);color:var(--fw-danger)}.fw-btn-lg{padding:14px 26px}.fw-btn:disabled,.fw-btn[aria-disabled=true]{opacity:.45;cursor:not-allowed;transform:none}.fw-btn-loading{cursor:progress}.fw-btn .fw-spinner{margin-right:2px}.fw-icon-btn{width:32px;height:32px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;color:var(--fw-text-soft);flex-shrink:0;padding:0;text-decoration:none;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease),color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-icon-btn:hover{border-color:var(--fw-secondary);color:var(--fw-secondary)}.fw-icon-btn:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-icon-btn svg{width:15px;height:15px}.fw-icon{display:inline-flex;width:1em;height:1em;color:inherit;vertical-align:-.125em}.fw-icon svg{width:100%;height:100%;display:block}.fw-card{background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-sm);padding:var(--fw-sp-5);color:var(--fw-text)}.fw-tag{display:inline-flex;align-items:center;gap:6px;font-family:var(--fw-font-mono);font-size:12px;font-weight:600;line-height:1.3;padding:5px 12px;border-radius:var(--fw-r-md);transform:rotate(-2deg);background:var(--fw-bg-dim);color:var(--fw-text-soft);white-space:nowrap}.fw-tag:nth-of-type(2n){transform:rotate(1.5deg)}.fw-tag:nth-of-type(3n){transform:rotate(-1deg)}.fw-tag-pill,.fw-tag-pill:nth-of-type(n){transform:none;font-size:11px;padding:4px 10px;border-radius:var(--fw-r-full)}.fw-tag-live{background:var(--fw-success-bg);color:var(--fw-success)}.fw-tag-live:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--fw-success)}.fw-tag-pending{background:var(--fw-warning-bg);color:var(--fw-warning)}.fw-tag-error{background:var(--fw-danger-bg);color:var(--fw-danger)}.fw-tag-info{background:var(--fw-info-bg);color:var(--fw-info)}.fw-tag-secondary{background:var(--fw-secondary-bg);color:var(--fw-secondary)}@media(prefers-reduced-motion:no-preference){.fw-tag{transition:transform var(--fw-motion-fast) var(--fw-motion-ease)}}.fw-eyebrow{display:inline-flex;align-items:center;gap:var(--fw-sp-2);font-family:var(--fw-font-mono);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fw-secondary);background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);padding:7px 16px;border-radius:var(--fw-r-full);box-shadow:var(--fw-shadow-sm)}.fw-eyebrow:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--fw-primary)}[data-theme=dark] .fw-eyebrow{color:var(--fw-secondary-hover)}.fw-field{display:flex;flex-direction:column;gap:6px;max-width:320px}.fw-field-full{max-width:none}.fw-label,.fw-field>label{font-size:13px;font-weight:600;color:var(--fw-text)}.fw-hint{font-size:12px;color:var(--fw-text-soft)}.fw-error-msg{font-size:12px;color:var(--fw-danger);font-weight:600}.fw-required{color:var(--fw-danger);font-weight:700;margin-left:3px}.fw-input,.fw-field input:not([type=checkbox]):not([type=radio]),.fw-field select,.fw-field textarea{font-family:var(--fw-font-body);font-size:15px;line-height:1.4;padding:11px 14px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);color:var(--fw-text);outline:none;width:100%;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease),background var(--fw-motion-base) var(--fw-motion-ease),color var(--fw-motion-base) var(--fw-motion-ease)}textarea.fw-input,.fw-field textarea{min-height:96px;resize:vertical}.fw-input::placeholder,.fw-field input::placeholder,.fw-field textarea::placeholder{color:var(--fw-text-soft);opacity:1}.fw-input:focus,.fw-field input:focus,.fw-field select:focus,.fw-field textarea:focus{border-color:var(--fw-primary-hover);box-shadow:var(--fw-focus-ring)}.fw-input.is-error,.fw-input[aria-invalid=true],.fw-field.is-error input,.fw-field.is-error select,.fw-field.is-error textarea,.fw-field input.is-error,.fw-field textarea.is-error{border-color:var(--fw-danger)}.fw-input:disabled,.fw-field input:disabled,.fw-field select:disabled,.fw-field textarea:disabled{background:var(--fw-bg-dim);color:var(--fw-text-soft);border-color:var(--fw-bg-dim);cursor:not-allowed}.fw-field.is-disabled .fw-label,.fw-field.is-disabled>label{color:var(--fw-text-soft)}.fw-checkbox,.fw-radio,.fw-toggle{position:relative;display:inline-flex;align-items:center;gap:10px;cursor:pointer;font-family:var(--fw-font-body);font-size:14px;font-weight:600;color:var(--fw-text)}.fw-checkbox input,.fw-radio input,.fw-toggle input{position:absolute;opacity:0;width:0;height:0;margin:0}.fw-checkbox:has(input:disabled),.fw-radio:has(input:disabled),.fw-toggle:has(input:disabled){cursor:not-allowed}.fw-checkbox input:disabled~span,.fw-radio input:disabled~span,.fw-toggle input:disabled~span{color:var(--fw-text-soft)}.fw-option-group{display:flex;flex-direction:column;gap:var(--fw-sp-3)}.fw-option-group-inline{flex-direction:row;flex-wrap:wrap;gap:var(--fw-sp-5)}.fw-checkbox .fw-box{width:20px;height:20px;border-radius:6px;border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background var(--fw-motion-fast) var(--fw-motion-ease),border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-checkbox .fw-box:after{content:"";width:12px;height:12px;opacity:0;background-color:var(--fw-on-primary);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3 8.5L6.2 11.5L13 4.5' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:opacity .1s var(--fw-motion-ease)}.fw-checkbox input:checked+.fw-box{background:var(--fw-primary);border-color:var(--fw-primary)}.fw-checkbox input:checked+.fw-box:after{opacity:1}.fw-checkbox input:indeterminate+.fw-box{background:var(--fw-primary);border-color:var(--fw-primary)}.fw-checkbox input:indeterminate+.fw-box:after{opacity:1;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8h9' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M3.5 8h9' stroke='%23000' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat}.fw-checkbox input:focus-visible+.fw-box{box-shadow:var(--fw-focus-ring)}.fw-checkbox input:disabled+.fw-box{background:var(--fw-bg-dim);border-color:var(--fw-bg-dim)}.fw-radio .fw-box{width:20px;height:20px;border-radius:50%;border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-radio .fw-box:after{content:"";width:10px;height:10px;border-radius:50%;background:transparent;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-radio input:checked+.fw-box{border-color:var(--fw-primary)}.fw-radio input:checked+.fw-box:after{background:var(--fw-primary)}.fw-radio input:focus-visible+.fw-box{box-shadow:var(--fw-focus-ring)}.fw-radio input:disabled+.fw-box{background:var(--fw-bg-dim);border-color:var(--fw-bg-dim)}.fw-toggle .fw-track{width:42px;height:24px;border-radius:var(--fw-r-full);background:var(--fw-bg-dim);position:relative;flex-shrink:0;transition:background .16s var(--fw-motion-ease)}.fw-toggle .fw-thumb{position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:var(--fw-surface);box-shadow:var(--fw-shadow-sm);transition:transform .16s var(--fw-motion-ease)}.fw-toggle input:checked+.fw-track{background:var(--fw-primary)}.fw-toggle input:checked+.fw-track .fw-thumb{transform:translate(18px)}.fw-toggle input:focus-visible+.fw-track{box-shadow:var(--fw-focus-ring)}.fw-toggle input:disabled+.fw-track{opacity:.5}.fw-combobox{position:relative}.fw-combobox-list{position:absolute;top:calc(100% + 6px);left:0;right:0;z-index:30;background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-md);box-shadow:var(--fw-shadow-lg);max-height:220px;overflow-y:auto;padding:6px;margin:0;list-style:none;opacity:0;transform:translateY(-4px);pointer-events:none;transition:opacity .14s var(--fw-motion-ease),transform .14s var(--fw-motion-ease)}.fw-combobox-list.is-open{opacity:1;transform:translateY(0);pointer-events:auto}.fw-combobox-option{padding:10px 12px;border-radius:var(--fw-r-sm);font-family:var(--fw-font-body);font-size:14px;cursor:pointer;color:var(--fw-text)}.fw-combobox-option:hover,.fw-combobox-option.is-active{background:var(--fw-bg)}.fw-combobox-option b{color:var(--fw-primary-hover);font-weight:700}.fw-combobox-empty{padding:14px 12px;font-size:13px;color:var(--fw-text-soft);text-align:center}@media(prefers-reduced-motion:reduce){.fw-combobox-list{transform:none}}.fw-alert{display:flex;gap:var(--fw-sp-3);padding:var(--fw-sp-4);border-radius:var(--fw-r-md);align-items:flex-start;font-family:var(--fw-font-body);color:var(--fw-text);background:var(--fw-bg-dim)}.fw-alert-dot{width:20px;height:20px;border-radius:50%;flex-shrink:0;margin-top:2px;background:var(--fw-text-soft)}.fw-alert-title{font-weight:700;font-size:14px}.fw-alert-body{font-size:13px;color:var(--fw-text-soft);margin-top:2px}.fw-alert-success{background:var(--fw-success-bg)}.fw-alert-success .fw-alert-dot{background:var(--fw-success)}.fw-alert-error{background:var(--fw-danger-bg)}.fw-alert-error .fw-alert-dot{background:var(--fw-danger)}.fw-alert-pending{background:var(--fw-warning-bg)}.fw-alert-pending .fw-alert-dot{background:var(--fw-warning)}.fw-alert-info{background:var(--fw-info-bg)}.fw-alert-info .fw-alert-dot{background:var(--fw-info)}.fw-alert-with-action{align-items:center;justify-content:space-between;flex-wrap:wrap}.fw-alert-with-action .fw-alert-main{display:flex;align-items:center;gap:var(--fw-sp-3)}.fw-progress-label{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:6px;font-family:var(--fw-font-body);font-size:13px}.fw-progress-name{font-weight:600;color:var(--fw-text)}.fw-progress-pct{font-family:var(--fw-font-mono);color:var(--fw-text-soft)}.fw-progress{position:relative;height:10px;border-radius:var(--fw-r-full);background:var(--fw-bg-dim);overflow:hidden}.fw-progress-sm{height:8px}.fw-progress-fill{height:100%;border-radius:var(--fw-r-full);background:var(--fw-primary);transition:width .4s var(--fw-motion-ease)}.fw-progress.is-success .fw-progress-fill,.fw-progress-fill.is-success{background:var(--fw-success)}.fw-progress.is-indeterminate .fw-progress-fill{position:absolute;width:40%;left:-40%;animation:fw-indeterminate-slide 1.4s ease-in-out infinite}@keyframes fw-indeterminate-slide{0%{left:-40%;width:40%}50%{width:60%}to{left:100%;width:40%}}@media(prefers-reduced-motion:reduce){.fw-progress.is-indeterminate .fw-progress-fill{position:static;width:100%;animation:fw-pulse-opacity 1.2s ease-in-out infinite}}.fw-spinner{display:inline-block;border-radius:50%;flex-shrink:0;width:24px;height:24px;border:3px solid var(--fw-bg-dim);border-top-color:currentColor;animation:fw-spin .8s linear infinite}.fw-spinner-sm{width:16px;height:16px;border-width:2px}.fw-spinner-md{width:24px;height:24px;border-width:3px}.fw-spinner-lg{width:40px;height:40px;border-width:4px}@keyframes fw-spin{to{transform:rotate(360deg)}}@keyframes fw-pulse-opacity{0%,to{opacity:1}50%{opacity:.35}}@media(prefers-reduced-motion:reduce){.fw-spinner{animation:fw-pulse-opacity 1.2s ease-in-out infinite;border-top-color:var(--fw-bg-dim)}}.fw-nav{position:relative;background:var(--fw-secondary);border-radius:var(--fw-r-lg);padding:var(--fw-sp-4) var(--fw-sp-5);display:flex;align-items:center;justify-content:space-between;gap:var(--fw-sp-4);box-shadow:var(--fw-shadow-md);font-family:var(--fw-font-body);color:var(--fw-on-secondary)}.fw-nav-sticky{position:sticky;top:var(--fw-sp-5);z-index:100}.fw-nav-brand{color:var(--fw-on-secondary);font-family:var(--fw-font-display);font-weight:800;font-size:18px;display:flex;align-items:center;gap:var(--fw-sp-2);text-decoration:none}.fw-nav-dot{width:10px;height:10px;border-radius:50%;background:var(--fw-primary)}.fw-nav-hex{width:16px;height:16px;background:var(--fw-primary);clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%)}.fw-nav-links{display:flex;gap:var(--fw-sp-5);align-items:center}.fw-nav-links a{color:var(--fw-on-secondary-soft);font-size:14px;font-weight:600;text-decoration:none;transition:color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-links a:hover{color:var(--fw-on-secondary)}.fw-nav-links a.is-active{color:var(--fw-on-secondary);border-bottom:2px solid var(--fw-primary);padding-bottom:3px}.fw-nav-right{display:flex;align-items:center;gap:var(--fw-sp-4)}.fw-nav-avatar{width:34px;height:34px;border-radius:var(--fw-r-sm);background:var(--fw-primary);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px;color:var(--fw-on-primary);font-family:var(--fw-font-display);border:none;padding:0;cursor:default}.fw-nav-btn,.fw-nav-toggle{width:38px;height:38px;border-radius:var(--fw-r-sm);background:var(--fw-on-secondary-fill);border:var(--fw-border-w) solid var(--fw-on-secondary-line);color:var(--fw-on-secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;font-size:15px;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-btn:hover,.fw-nav-toggle:hover{background:var(--fw-on-secondary-line)}.fw-nav-btn:focus-visible,.fw-nav-toggle:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-nav-toggle{display:none;flex-direction:column;gap:4px}.fw-nav-toggle span{width:16px;height:2px;background:var(--fw-on-secondary);border-radius:2px;transition:transform var(--fw-motion-base) var(--fw-motion-ease),opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-nav-toggle[aria-expanded=true] span:nth-child(1){transform:translateY(6px) rotate(45deg)}.fw-nav-toggle[aria-expanded=true] span:nth-child(2){opacity:0}.fw-nav-toggle[aria-expanded=true] span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}.fw-nav-dropdown{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:20;background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-lg);padding:var(--fw-sp-3);display:flex;flex-direction:column;gap:2px;opacity:0;transform:translateY(-6px) scale(.98);pointer-events:none;transition:opacity .16s var(--fw-motion-ease),transform .16s var(--fw-motion-ease)}.fw-nav-dropdown.is-open{opacity:1;transform:translateY(0) scale(1);pointer-events:auto}.fw-nav-dropdown-menu{left:auto;min-width:200px}.fw-nav-dropdown a,.fw-nav-dropdown button{color:var(--fw-text);font-family:var(--fw-font-body);font-size:15px;font-weight:600;text-decoration:none;text-align:left;padding:12px 14px;border-radius:var(--fw-r-sm);background:none;border:none;cursor:pointer;transition:background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-nav-dropdown a:hover,.fw-nav-dropdown button:hover{background:var(--fw-bg)}.fw-nav-dropdown a.is-active{background:var(--fw-primary);color:var(--fw-on-primary)}@media(max-width:600px){.fw-nav-links{display:none}.fw-nav-toggle{display:flex}}@media(prefers-reduced-motion:reduce){.fw-nav-dropdown{transform:none}}.fw-stat-label{font-family:var(--fw-font-body);font-size:13px;color:var(--fw-text-soft);font-weight:600}.fw-stat-value{font-family:var(--fw-font-display);font-size:32px;font-weight:800;line-height:1.1;color:var(--fw-text);margin-top:4px}.fw-stat-value .fw-stat-unit{font-size:18px;color:var(--fw-primary-hover)}.fw-stat-delta{font-family:var(--fw-font-mono);font-size:12px;font-weight:600;color:var(--fw-text-soft);margin-top:4px}.fw-stat-delta.is-up{color:var(--fw-success)}.fw-stat-delta.is-down{color:var(--fw-danger)}.fw-empty{text-align:center;padding:var(--fw-sp-7) var(--fw-sp-5);font-family:var(--fw-font-body)}.fw-empty-blob{width:72px;height:72px;margin:0 auto var(--fw-sp-4);border-radius:38% 62% 60% 40%/48% 42% 58% 52%;background:linear-gradient(135deg,var(--fw-primary),var(--fw-primary-soft));color:var(--fw-on-primary);display:flex;align-items:center;justify-content:center;font-size:28px}.fw-empty-title{font-family:var(--fw-font-display);font-size:17px;font-weight:700;color:var(--fw-text);margin:0 0 6px}.fw-empty-body{font-size:14px;color:var(--fw-text-soft);max-width:36ch;margin:0 auto var(--fw-sp-4)}.fw-modal-overlay{position:fixed;inset:0;background:var(--fw-overlay);display:flex;align-items:center;justify-content:center;padding:var(--fw-sp-5);z-index:100;opacity:0;pointer-events:none;transition:opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-modal-overlay.is-open{opacity:1;pointer-events:auto}.fw-modal{background:var(--fw-surface);color:var(--fw-text);font-family:var(--fw-font-body);border-radius:var(--fw-r-xl);box-shadow:var(--fw-shadow-lg);overflow:hidden;width:100%;max-width:460px;transform:translateY(8px) scale(.98);transition:transform var(--fw-motion-base) var(--fw-motion-ease)}.fw-modal-scroll{max-height:88vh;overflow-y:auto;padding:var(--fw-sp-6)}.fw-modal-wide{max-width:600px}.fw-modal-overlay.is-open .fw-modal{transform:translateY(0) scale(1)}.fw-modal-head{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--fw-sp-3);margin-bottom:var(--fw-sp-5)}.fw-modal-head h2,.fw-modal-title{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);margin:0}.fw-modal-sub{font-size:13px;color:var(--fw-text-soft);margin:2px 0 0}.fw-modal-foot{display:flex;justify-content:flex-end;gap:var(--fw-sp-3);align-items:center;margin-top:var(--fw-sp-2);padding-top:var(--fw-sp-5);border-top:var(--fw-border-w) solid var(--fw-bg-dim)}@media(prefers-reduced-motion:reduce){.fw-modal{transform:none}}.fw-drawer-overlay{position:fixed;inset:0;background:var(--fw-overlay-soft);opacity:0;pointer-events:none;transition:opacity var(--fw-motion-base) var(--fw-motion-ease);z-index:90}.fw-drawer-overlay.is-open{opacity:1;pointer-events:auto}.fw-drawer{position:fixed;top:0;right:0;height:100%;width:440px;max-width:92vw;background:var(--fw-bg);color:var(--fw-text);font-family:var(--fw-font-body);box-shadow:var(--fw-shadow-lg);border-left:var(--fw-border-w) solid var(--fw-bg-dim);transform:translate(100%);transition:transform .24s var(--fw-motion-ease);z-index:91;display:flex;flex-direction:column}.fw-drawer.is-open{transform:translate(0)}.fw-drawer-head{padding:var(--fw-sp-5);border-bottom:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);display:flex;align-items:flex-start;gap:var(--fw-sp-3);flex-shrink:0}.fw-drawer-head-text{flex:1;min-width:0}.fw-drawer-eyebrow{font-family:var(--fw-font-mono);font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--fw-text-soft);margin-bottom:4px}.fw-drawer-title{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);margin:0}.fw-drawer-title-input{font-family:var(--fw-font-display);font-size:19px;font-weight:800;color:var(--fw-text);border:none;background:transparent;padding:2px 0;width:100%;outline:none;border-radius:6px}.fw-drawer-title-input:focus{background:var(--fw-bg);padding:2px 6px;margin:0 -6px}.fw-drawer>form{flex:1;min-height:0;display:flex;flex-direction:column}.fw-drawer-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:var(--fw-sp-5);display:flex;flex-direction:column;gap:var(--fw-sp-5)}.fw-drawer-foot{padding:var(--fw-sp-4) var(--fw-sp-5);display:flex;align-items:center;justify-content:space-between;gap:var(--fw-sp-3);flex-shrink:0;border-top:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface)}@media(max-width:560px){.fw-drawer{left:0;width:auto;max-width:none}}@media(prefers-reduced-motion:reduce){.fw-drawer{transition:opacity var(--fw-motion-base) var(--fw-motion-ease);transform:none;opacity:0;pointer-events:none}.fw-drawer.is-open{opacity:1;pointer-events:auto}}.fw-popover{position:fixed;top:0;left:0;z-index:40;width:max-content;max-width:min(320px,calc(100vw - 2 * var(--fw-sp-4)));background:var(--fw-surface);color:var(--fw-text);font-family:var(--fw-font-body);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-lg);box-shadow:var(--fw-shadow-lg);padding:var(--fw-sp-4);opacity:0;transform:scale(.98);pointer-events:none;transition:opacity var(--fw-motion-base) var(--fw-motion-ease),transform var(--fw-motion-base) var(--fw-motion-ease)}.fw-popover.is-open{opacity:1;transform:scale(1);pointer-events:auto}.fw-popover-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fw-sp-3);margin-bottom:var(--fw-sp-3)}.fw-popover-title{font-family:var(--fw-font-display);font-size:15px;font-weight:700;color:var(--fw-text);margin:0}.fw-popover-body{font-size:13px;color:var(--fw-text-soft)}@media(prefers-reduced-motion:reduce){.fw-popover{transform:none}}.fw-toast{position:fixed;bottom:var(--fw-sp-6);right:var(--fw-sp-6);z-index:200;display:flex;align-items:center;gap:var(--fw-sp-3);max-width:min(360px,calc(100vw - 2 * var(--fw-sp-5)));background:var(--fw-success-bg);color:var(--fw-text);font-family:var(--fw-font-body);border-radius:var(--fw-r-md);padding:var(--fw-sp-3) var(--fw-sp-4);box-shadow:var(--fw-shadow-lg);font-size:13px;font-weight:600;transform:translateY(12px);opacity:0;pointer-events:none;transition:transform var(--fw-motion-base) var(--fw-motion-ease),opacity var(--fw-motion-base) var(--fw-motion-ease)}.fw-toast.is-show{transform:translateY(0);opacity:1;pointer-events:auto}.fw-toast-dot{width:8px;height:8px;border-radius:50%;background:var(--fw-success);flex-shrink:0}.fw-toast-error{background:var(--fw-danger-bg)}.fw-toast-error .fw-toast-dot{background:var(--fw-danger)}.fw-toast-info{background:var(--fw-info-bg)}.fw-toast-info .fw-toast-dot{background:var(--fw-info)}.fw-toast-pending{background:var(--fw-warning-bg)}.fw-toast-pending .fw-toast-dot{background:var(--fw-warning)}@media(prefers-reduced-motion:reduce){.fw-toast{transform:none}}.fw-list-row{display:block;background:var(--fw-surface);border-radius:var(--fw-r-lg);border:var(--fw-border-w) solid var(--fw-bg-dim);box-shadow:var(--fw-shadow-sm);padding:var(--fw-sp-4) var(--fw-sp-5);color:inherit;font-family:var(--fw-font-body);text-decoration:none;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),box-shadow var(--fw-motion-fast) var(--fw-motion-ease)}.fw-list-row:hover{transform:translateY(-1px);box-shadow:var(--fw-shadow-md);text-decoration:none}.fw-list-row:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-list-row.is-locked{opacity:.6}.fw-list-row.is-locked:hover{transform:none;box-shadow:var(--fw-shadow-sm)}.fw-list-row+.fw-list-row{margin-top:var(--fw-sp-3)}.fw-list-row-main{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fw-sp-2) var(--fw-sp-4)}.fw-list-row-title{font-family:var(--fw-font-display);font-weight:700;font-size:16px;color:var(--fw-text)}.fw-list-row-meta{font-size:13px;color:var(--fw-text-soft)}.fw-sub-list{margin:var(--fw-sp-2) 0 0 var(--fw-sp-5);padding-left:var(--fw-sp-4);border-left:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-sub-list-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--fw-sp-2) var(--fw-sp-3);padding:var(--fw-sp-2) 0}.fw-sub-list-row+.fw-sub-list-row{border-top:1px solid var(--fw-bg-dim)}.fw-sub-list-title{font-size:13.5px;font-weight:600;color:var(--fw-text)}.fw-disclosure>summary{cursor:pointer;color:var(--fw-secondary);font-family:var(--fw-font-body);font-weight:600;font-size:13px;list-style:none;display:flex;align-items:center;gap:6px}.fw-disclosure>summary::-webkit-details-marker{display:none}.fw-disclosure>summary:hover{text-decoration:underline}.fw-disclosure>summary:focus-visible{outline:none;border-radius:4px;box-shadow:var(--fw-focus-ring)}.fw-disclosure-chevron{width:12px;height:12px;flex-shrink:0;transition:transform .15s var(--fw-motion-ease)}.fw-disclosure[open]>summary .fw-disclosure-chevron{transform:rotate(180deg)}.fw-disclosure-count{font-family:var(--fw-font-mono);font-size:10.5px;font-weight:700;color:var(--fw-secondary);background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-full);padding:1px 7px}.fw-disclosure-body{margin-top:var(--fw-sp-3);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-md);padding:var(--fw-sp-4);background:var(--fw-bg);display:flex;flex-direction:column;gap:var(--fw-sp-3)}.fw-menu{--fw-menu-indent: var(--fw-sp-4);--fw-menu-row-h: 36px;font-family:var(--fw-font-body);color:var(--fw-text)}.fw-menu-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}.fw-menu-group>.fw-menu-list{margin:2px 0 0 var(--fw-menu-indent);padding-left:var(--fw-sp-3);border-left:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-menu-link,.fw-menu-summary{display:flex;align-items:center;gap:var(--fw-sp-2);min-height:var(--fw-menu-row-h);padding:0 var(--fw-sp-3);border-radius:var(--fw-r-sm);color:var(--fw-text);font-family:var(--fw-font-body);font-size:14px;font-weight:600;line-height:1.3;text-decoration:none;text-align:left;background:none;border:none;cursor:pointer;transition:background-color var(--fw-motion-fast) var(--fw-motion-ease),color var(--fw-motion-fast) var(--fw-motion-ease)}@media(hover:hover){.fw-menu-link:hover,.fw-menu-summary:hover{background:var(--fw-bg);text-decoration:none}}.fw-menu-link:focus-visible,.fw-menu-summary:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-menu-link[aria-current=page]{background:var(--fw-secondary-bg);color:var(--fw-secondary)}.fw-menu-summary.is-current{color:var(--fw-secondary)}.fw-menu-summary{list-style:none;user-select:none}.fw-menu-summary::-webkit-details-marker{display:none}.fw-menu-summary:after{content:"";flex-shrink:0;width:16px;height:16px;margin-left:auto;background-color:currentColor;opacity:.55;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M6 4l4 4-4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M6 4l4 4-4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:transform var(--fw-motion-fast) var(--fw-motion-ease),opacity var(--fw-motion-fast) var(--fw-motion-ease)}.fw-menu-summary:hover:after,.fw-menu-summary.is-current:after{opacity:1}.fw-menu-group[open]>.fw-menu-summary:after{transform:rotate(90deg)}.fw-menu-split{position:relative}.fw-menu-split>.fw-menu-link{padding-right:44px}.fw-menu-summary-icon{position:absolute;top:0;right:0;width:var(--fw-menu-row-h);height:var(--fw-menu-row-h);min-height:0;padding:0;justify-content:center}.fw-menu-summary-icon:after{margin-left:0}.fw-menu-panel{padding:var(--fw-sp-2) var(--fw-sp-3) var(--fw-sp-4);color:var(--fw-text-soft);font-size:14px;line-height:1.5}.fw-menu-panel>:first-child{margin-top:0}.fw-menu-panel>:last-child{margin-bottom:0}.fw-menu-accordion>.fw-menu-group+.fw-menu-group{border-top:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary{min-height:44px;padding-inline:0;border-radius:0;font-family:var(--fw-font-display);font-size:15px;font-weight:700}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:after{-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}.fw-menu-accordion>.fw-menu-group[open]>.fw-menu-summary:after{transform:rotate(180deg)}@media(hover:hover){.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:hover{background:none;color:var(--fw-secondary)}}.fw-menu-accordion>.fw-menu-group>.fw-menu-summary:focus-visible{border-radius:4px}.fw-menu-accordion>.fw-menu-group>.fw-menu-panel{padding-inline:0}@media(prefers-reduced-motion:reduce){.fw-menu-summary:after{transition:none}}.fw-pagination{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--fw-sp-3);font-family:var(--fw-font-body)}.fw-pag-info,.fw-pag-label{font-family:var(--fw-font-mono);font-size:12px;color:var(--fw-text-soft)}.fw-pag-controls{display:flex;align-items:center;gap:var(--fw-sp-3)}.fw-btn-page{display:inline-flex;align-items:center;height:34px;padding:0 14px;border-radius:var(--fw-r-sm);border:var(--fw-border-w) solid var(--fw-bg-dim);background:var(--fw-surface);color:var(--fw-text);font-family:var(--fw-font-body);font-size:13px;font-weight:600;text-decoration:none;cursor:pointer;transition:border-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-btn-page:hover{border-color:var(--fw-text-soft);text-decoration:none}.fw-btn-page:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-btn-page.is-disabled,.fw-btn-page[aria-disabled=true],.fw-btn-page:disabled{opacity:.35;cursor:not-allowed;pointer-events:none}.fw-table-wrap{overflow:hidden;background:var(--fw-surface);border:var(--fw-border-w) solid var(--fw-bg-dim);border-radius:var(--fw-r-lg);box-shadow:var(--fw-shadow-sm);font-family:var(--fw-font-body);color:var(--fw-text)}.fw-table-scroll{overflow-x:auto}.fw-table-scroll:focus-visible{outline:none}.fw-table-wrap:has(.fw-table-scroll:focus-visible){box-shadow:var(--fw-focus-ring)}.fw-table-wrap.fw-table-sticky .fw-table-scroll{max-height:var(--fw-table-max-height, 460px);overflow:auto}.fw-table-sticky .fw-table thead th{position:sticky;top:0;z-index:1}.fw-table{width:100%;border-collapse:separate;border-spacing:0;font-family:var(--fw-font-body);font-size:14px;line-height:1.4;color:var(--fw-text);text-align:left}.fw-table caption{caption-side:top;text-align:left;font-family:var(--fw-font-display);font-weight:700;font-size:16px;color:var(--fw-text);padding:var(--fw-sp-4) var(--fw-sp-5) var(--fw-sp-2)}.fw-table th,.fw-table td{padding:var(--fw-sp-3) var(--fw-sp-4);vertical-align:middle}.fw-table th:first-child,.fw-table td:first-child{padding-left:var(--fw-sp-5)}.fw-table th:last-child,.fw-table td:last-child{padding-right:var(--fw-sp-5)}.fw-table thead th{font-size:12px;font-weight:700;letter-spacing:.02em;color:var(--fw-text-soft);background:var(--fw-surface);border-bottom:var(--fw-border-w) solid var(--fw-bg-dim);white-space:nowrap}.fw-table tbody tr+tr>td{border-top:var(--fw-border-w) solid var(--fw-bg-dim)}.fw-table tbody td{transition:background-color var(--fw-motion-fast) var(--fw-motion-ease)}.fw-table-striped tbody tr:nth-child(2n)>td{background:var(--fw-bg)}@media(hover:hover){.fw-table tbody tr:hover>td{background:var(--fw-secondary-bg)}}.fw-table tbody tr.is-selected>td,.fw-table tbody tr[aria-selected=true]>td{background:var(--fw-secondary-bg)}.fw-table tbody tr.is-selected>td:first-child,.fw-table tbody tr[aria-selected=true]>td:first-child{box-shadow:inset 3px 0 0 var(--fw-secondary)}.fw-table-compact th,.fw-table-compact td{padding:var(--fw-sp-2) var(--fw-sp-3);font-size:13px}.fw-table-compact th:first-child,.fw-table-compact td:first-child{padding-left:var(--fw-sp-4)}.fw-table-compact th:last-child,.fw-table-compact td:last-child{padding-right:var(--fw-sp-4)}.fw-table-num{font-family:var(--fw-font-mono);text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}.fw-table-num .fw-table-sort{flex-direction:row-reverse}.fw-table-select{width:1%;padding-right:0;box-sizing:border-box}.fw-table-select .fw-checkbox{gap:0;vertical-align:middle}.fw-table-actions{width:1%;text-align:right;white-space:nowrap;box-sizing:border-box}.fw-table-actions .fw-icon-btn{vertical-align:middle}.fw-table-actions>*+*{margin-left:var(--fw-sp-1)}.fw-table-empty>td{text-align:center;padding:var(--fw-sp-7) var(--fw-sp-5);color:var(--fw-text-soft);font-family:var(--fw-font-display)}.fw-table-empty:hover>td{background:transparent}.fw-table-loading>td{text-align:center;padding:var(--fw-sp-6) var(--fw-sp-5)}.fw-table[aria-busy=true] tbody,.fw-table.is-loading tbody{opacity:.5;pointer-events:none;transition:opacity var(--fw-motion-fast) var(--fw-motion-ease)}th[data-fw-sort]{cursor:pointer}.fw-table-sort{display:inline-flex;align-items:center;gap:var(--fw-sp-1);padding:2px 4px;margin:-2px -4px;border:0;background:none;font:inherit;color:inherit;letter-spacing:inherit;cursor:pointer;border-radius:6px}th[data-fw-sort]:hover .fw-table-sort,th[aria-sort=ascending] .fw-table-sort,th[aria-sort=descending] .fw-table-sort{color:var(--fw-text)}.fw-table-sort:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-table-sort:after{content:"";width:12px;height:12px;flex-shrink:0;background-color:currentColor;opacity:.35;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M5 6.5l3-3 3 3M5 9.5l3 3 3-3' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M5 6.5l3-3 3 3M5 9.5l3 3 3-3' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;transition:opacity var(--fw-motion-fast) var(--fw-motion-ease)}th[aria-sort=ascending] .fw-table-sort:after{opacity:1;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 10l4-4 4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 10l4-4 4 4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}th[aria-sort=descending] .fw-table-sort:after{opacity:1;-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%23000' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}@media(max-width:560px){.fw-table{table-layout:fixed}.fw-table-select{width:var(--fw-table-select-w, 44px)}.fw-table-actions{width:var(--fw-table-actions-w, 96px)}.fw-table td:not(.fw-table-select):not(.fw-table-actions):not(.fw-table-num){white-space:normal;overflow-wrap:anywhere}.fw-table-num,.fw-table th{overflow:hidden;text-overflow:ellipsis}}.fw-tablist{display:flex;gap:var(--fw-sp-2);border-bottom:var(--fw-border-w) solid var(--fw-bg-dim);overflow-x:auto;scrollbar-width:none}.fw-tablist::-webkit-scrollbar{display:none}.fw-tablist[aria-orientation=vertical]{flex-direction:column;align-items:flex-start;border-bottom:none;border-right:var(--fw-border-w) solid var(--fw-bg-dim);overflow-x:visible;overflow-y:auto}.fw-tab{appearance:none;background:transparent;border:none;border-bottom:2px solid transparent;border-radius:var(--fw-r-sm) var(--fw-r-sm) 0 0;font-family:var(--fw-font-body);font-weight:600;font-size:13px;color:var(--fw-text-soft);padding:var(--fw-sp-3) var(--fw-sp-4);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--fw-motion-fast) var(--fw-motion-ease),border-color var(--fw-motion-fast) var(--fw-motion-ease),background var(--fw-motion-fast) var(--fw-motion-ease)}.fw-tablist[aria-orientation=vertical] .fw-tab{border-bottom:none;border-right:2px solid transparent;border-radius:var(--fw-r-sm) 0 0 var(--fw-r-sm);text-align:left;width:100%}.fw-tab:hover:not([aria-selected=true]):not([aria-disabled=true]){color:var(--fw-text);background:var(--fw-bg-dim)}.fw-tab[aria-selected=true]{color:var(--fw-text);border-color:var(--fw-secondary)}.fw-tab:focus-visible{outline:none;box-shadow:var(--fw-focus-ring)}.fw-tab[aria-disabled=true]{opacity:.45;cursor:not-allowed}.fw-tabpanel{padding:var(--fw-sp-4) 0}.fw-tabpanel:focus-visible{outline:none;border-radius:var(--fw-r-sm);box-shadow:var(--fw-focus-ring)}@media(prefers-reduced-motion:reduce){.fw-tab{transition:none}}.fw-tooltip{position:fixed;top:0;left:0;z-index:50;max-width:220px;background:var(--fw-text);color:var(--fw-bg);font-family:var(--fw-font-body);font-size:12.5px;font-weight:600;line-height:1.4;border-radius:var(--fw-r-sm);padding:6px 10px;box-shadow:var(--fw-shadow-md);opacity:0;transform:scale(.96);pointer-events:none;transition:opacity var(--fw-motion-fast) var(--fw-motion-ease),transform var(--fw-motion-fast) var(--fw-motion-ease);--fw-tooltip-arrow: 5px}.fw-tooltip.is-open{opacity:1;transform:scale(1);pointer-events:auto}.fw-tooltip:after{content:"";position:absolute;width:0;height:0;border:var(--fw-tooltip-arrow) solid transparent}.fw-tooltip[data-placement^=top]:after{top:100%;left:var(--fw-tooltip-arrow-pos, 50%);transform:translate(-50%);border-top-color:var(--fw-text);border-bottom-width:0}.fw-tooltip[data-placement^=bottom]:after{bottom:100%;left:var(--fw-tooltip-arrow-pos, 50%);transform:translate(-50%);border-bottom-color:var(--fw-text);border-top-width:0}.fw-tooltip[data-placement=left]:after{left:100%;top:var(--fw-tooltip-arrow-pos, 50%);transform:translateY(-50%);border-left-color:var(--fw-text);border-right-width:0}.fw-tooltip[data-placement=right]:after{right:100%;top:var(--fw-tooltip-arrow-pos, 50%);transform:translateY(-50%);border-right-color:var(--fw-text);border-left-width:0}@media(prefers-reduced-motion:reduce){.fw-tooltip{transform:none}}.fw-root,.fw-modal-scroll,.fw-drawer-body,.fw-table-scroll{scrollbar-width:thin;scrollbar-color:var(--fw-scrollbar-thumb) var(--fw-scrollbar-track)}.fw-root::-webkit-scrollbar,.fw-modal-scroll::-webkit-scrollbar,.fw-drawer-body::-webkit-scrollbar,.fw-table-scroll::-webkit-scrollbar{width:var(--fw-sp-2);height:var(--fw-sp-2)}.fw-root::-webkit-scrollbar-track,.fw-modal-scroll::-webkit-scrollbar-track,.fw-drawer-body::-webkit-scrollbar-track{background:var(--fw-scrollbar-track)}.fw-root::-webkit-scrollbar-thumb,.fw-modal-scroll::-webkit-scrollbar-thumb,.fw-drawer-body::-webkit-scrollbar-thumb,.fw-table-scroll::-webkit-scrollbar-thumb{background-color:var(--fw-scrollbar-thumb);border-radius:var(--fw-r-full);border:2px solid var(--fw-surface)}.fw-root::-webkit-scrollbar-thumb:hover,.fw-modal-scroll::-webkit-scrollbar-thumb:hover,.fw-drawer-body::-webkit-scrollbar-thumb:hover,.fw-table-scroll::-webkit-scrollbar-thumb:hover{background-color:var(--fw-scrollbar-thumb-hover)}.fw-table-scroll{scrollbar-color:var(--fw-scrollbar-thumb) var(--fw-bg-dim)}.fw-table-scroll::-webkit-scrollbar-track{background:var(--fw-bg-dim)}.fw-tablist:not([aria-orientation=vertical]){mask-image:linear-gradient(to right,transparent,black 24px,black calc(100% - 24px),transparent);-webkit-mask-image:linear-gradient(to right,transparent,black 24px,black calc(100% - 24px),transparent)}.fw-tablist[aria-orientation=vertical]{mask-image:linear-gradient(to bottom,transparent,black 24px,black calc(100% - 24px),transparent);-webkit-mask-image:linear-gradient(to bottom,transparent,black 24px,black calc(100% - 24px),transparent)}
|
package/dist/fernwell.tokens.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! fernwell v0.
|
|
1
|
+
/*! fernwell v0.4.0 | MIT | https://github.com/JacobKnaack/fernwell */
|
|
2
2
|
/* src/css/tokens.css */
|
|
3
3
|
@layer fw-tokens {
|
|
4
4
|
:root,
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
--fw-overlay: rgba(31, 36, 48, 0.55);
|
|
31
31
|
--fw-overlay-soft: rgba(31, 36, 48, 0.32);
|
|
32
32
|
--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);
|
|
33
|
+
--fw-scrollbar-thumb: var(--fw-text-soft);
|
|
34
|
+
--fw-scrollbar-thumb-hover: color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%);
|
|
35
|
+
--fw-scrollbar-track: transparent;
|
|
33
36
|
--fw-font-display:
|
|
34
37
|
"Plus Jakarta Sans",
|
|
35
38
|
system-ui,
|
|
@@ -96,6 +99,9 @@
|
|
|
96
99
|
--fw-overlay: rgba(0, 0, 0, 0.6);
|
|
97
100
|
--fw-overlay-soft: rgba(0, 0, 0, 0.4);
|
|
98
101
|
--fw-focus-ring: 0 0 0 4px color-mix(in srgb, var(--fw-primary) 25%, transparent);
|
|
102
|
+
--fw-scrollbar-thumb: var(--fw-text-soft);
|
|
103
|
+
--fw-scrollbar-thumb-hover: color-mix(in srgb, var(--fw-text-soft), var(--fw-text) 15%);
|
|
104
|
+
--fw-scrollbar-track: transparent;
|
|
99
105
|
--fw-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
100
106
|
--fw-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35);
|
|
101
107
|
--fw-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.45);
|
package/dist/icon.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon — renders a named SVG icon into a `data-fw-icon` element.
|
|
3
|
+
*
|
|
4
|
+
* <span class="fw-icon" data-fw-icon="trash" aria-hidden="true"></span>
|
|
5
|
+
*
|
|
6
|
+
* Icons are decorative by default (the injected <svg> is `aria-hidden` and
|
|
7
|
+
* `focusable="false"`); give the accessible name to a wrapping interactive
|
|
8
|
+
* element instead (e.g. `aria-label` on a button), same as `.fw-icon-btn`.
|
|
9
|
+
* Color and size are not set here — `.fw-icon` inherits `color` and sizes
|
|
10
|
+
* itself in `em`, so an icon matches whatever text surrounds it.
|
|
11
|
+
*/
|
|
12
|
+
declare const icons: Record<string, string>;
|
|
13
|
+
export type IconName = keyof typeof icons;
|
|
14
|
+
export declare function render(name: string): string;
|
|
15
|
+
export declare function init(root?: ParentNode): void;
|
|
16
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -14,12 +14,20 @@ import * as loading from './loading';
|
|
|
14
14
|
import * as toast from './toast';
|
|
15
15
|
import * as table from './table';
|
|
16
16
|
import * as menu from './menu';
|
|
17
|
-
|
|
17
|
+
import * as icon from './icon';
|
|
18
|
+
import * as popover from './popover';
|
|
19
|
+
import * as tooltip from './tooltip';
|
|
20
|
+
import * as tabs from './tabs';
|
|
21
|
+
export { theme, combobox, modal, nav, loading, toast, table, menu, icon, popover, tooltip, tabs };
|
|
18
22
|
export type { Theme, TokenOverrides, TokenThemeOverrides } from './theme';
|
|
19
23
|
export type { ComboboxOptions, ComboboxInstance } from './combobox';
|
|
20
24
|
export type { ToastVariant, ToastOptions } from './toast';
|
|
21
25
|
export type { SortDirection, SortDetail, SelectDetail } from './table';
|
|
22
26
|
export type { ToggleDetail } from './menu';
|
|
27
|
+
export type { IconName } from './icon';
|
|
28
|
+
export type { PopoverOptions, PopoverInstance } from './popover';
|
|
29
|
+
export type { TooltipOptions, TooltipInstance } from './tooltip';
|
|
30
|
+
export type { TabsOptions, TabsInstance, TabsActivation, TabsChangeDetail } from './tabs';
|
|
23
31
|
export declare const version = "__FW_VERSION__";
|
|
24
32
|
/**
|
|
25
33
|
* Wire every `data-fw-*` hook under `root`. Safe to call more than once —
|
|
@@ -38,5 +46,9 @@ declare const Fernwell: {
|
|
|
38
46
|
toast: typeof toast;
|
|
39
47
|
table: typeof table;
|
|
40
48
|
menu: typeof menu;
|
|
49
|
+
icon: typeof icon;
|
|
50
|
+
popover: typeof popover;
|
|
51
|
+
tooltip: typeof tooltip;
|
|
52
|
+
tabs: typeof tabs;
|
|
41
53
|
};
|
|
42
54
|
export default Fernwell;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Popover — a non-modal floating panel anchored to its trigger.
|
|
3
|
+
*
|
|
4
|
+
* <button type="button" data-fw-popover-trigger="settings-pop">Settings</button>
|
|
5
|
+
*
|
|
6
|
+
* <div class="fw-popover" id="settings-pop">
|
|
7
|
+
* <div class="fw-popover-head">
|
|
8
|
+
* <h3 class="fw-popover-title">Settings</h3>
|
|
9
|
+
* <button type="button" class="fw-icon-btn" data-fw-popover-close aria-label="Close">
|
|
10
|
+
* <span data-fw-icon="close" aria-hidden="true"></span>
|
|
11
|
+
* </button>
|
|
12
|
+
* </div>
|
|
13
|
+
* <div class="fw-popover-body">…</div>
|
|
14
|
+
* </div>
|
|
15
|
+
*
|
|
16
|
+
* Optional trigger attributes: `data-fw-popover-placement` ("top" | "bottom" |
|
|
17
|
+
* "left" | "right" — centered on the trigger's cross-axis midpoint — or a
|
|
18
|
+
* corner variant "top-left" | "top-right" | "bottom-left" | "bottom-right"
|
|
19
|
+
* that leans the panel toward that corner instead of centering it, e.g. to
|
|
20
|
+
* steer it clear of something else on the page; default "bottom"),
|
|
21
|
+
* `data-fw-popover-offset` (px, default 8).
|
|
22
|
+
*
|
|
23
|
+
* While open, the panel is moved to the end of <body> so its `position: fixed`
|
|
24
|
+
* containing block is always the viewport — not an ancestor with `transform`,
|
|
25
|
+
* `filter` or `contain` (e.g. a card, or another modal) that would otherwise
|
|
26
|
+
* break the positioning math — and moved back to its authored location on close.
|
|
27
|
+
*
|
|
28
|
+
* This is a non-modal dialog (`aria-modal="false"`), so per WAI-ARIA APG it
|
|
29
|
+
* does NOT trap Tab — focus is allowed to move naturally out of the panel.
|
|
30
|
+
* Closing on focus leaving the panel/trigger (`focusout`) does the equivalent
|
|
31
|
+
* job without fighting the surrounding page's tab order.
|
|
32
|
+
*
|
|
33
|
+
* Events (bubbling, from the panel): `fw:open`, `fw:close`.
|
|
34
|
+
*/
|
|
35
|
+
import { type Placement } from './_position';
|
|
36
|
+
export interface PopoverOptions {
|
|
37
|
+
placement?: Placement;
|
|
38
|
+
offset?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface PopoverInstance {
|
|
41
|
+
open(): void;
|
|
42
|
+
close(): void;
|
|
43
|
+
toggle(): void;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
}
|
|
46
|
+
export declare function popover(trigger: HTMLElement, panel: HTMLElement, opts?: PopoverOptions): PopoverInstance;
|
|
47
|
+
/** Wire every `[data-fw-popover-trigger]` under `root`. */
|
|
48
|
+
export declare function init(root?: ParentNode): void;
|
package/dist/tabs.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tabs — a single-selection tablist that switches between panels.
|
|
3
|
+
*
|
|
4
|
+
* <div class="fw-tablist" role="tablist" aria-label="Account settings" data-fw-tabs>
|
|
5
|
+
* <button type="button" class="fw-tab" id="tab-profile" role="tab" aria-selected="true" aria-controls="panel-profile">Profile</button>
|
|
6
|
+
* <button type="button" class="fw-tab" id="tab-billing" role="tab" aria-selected="false" aria-controls="panel-billing">Billing</button>
|
|
7
|
+
* </div>
|
|
8
|
+
* <div class="fw-tabpanel" id="panel-profile" role="tabpanel" aria-labelledby="tab-profile" tabindex="0">…</div>
|
|
9
|
+
* <div class="fw-tabpanel" id="panel-billing" role="tabpanel" aria-labelledby="tab-billing" tabindex="0" hidden>…</div>
|
|
10
|
+
*
|
|
11
|
+
* Author `aria-selected="true"` on the tab that should start selected (the
|
|
12
|
+
* rest `"false"`); `init()` derives roving `tabIndex` (0 on the selected tab,
|
|
13
|
+
* -1 on the rest) and each panel's `hidden` from that. Falls back to the
|
|
14
|
+
* first non-disabled tab if none is marked selected. A tab may carry
|
|
15
|
+
* `aria-disabled="true"` to make it non-interactive — it is skipped by
|
|
16
|
+
* click, arrow-key, and Home/End navigation.
|
|
17
|
+
*
|
|
18
|
+
* `data-fw-tabs-activation="manual"` on the tablist switches from the
|
|
19
|
+
* default "automatic" activation (arrow keys move focus AND select) to
|
|
20
|
+
* "manual" (arrow keys only move focus; Space/Enter selects the focused
|
|
21
|
+
* tab) — use manual when selecting a tab is expensive (e.g. triggers a
|
|
22
|
+
* fetch).
|
|
23
|
+
*
|
|
24
|
+
* `aria-orientation="vertical"` on the tablist swaps the primary arrow keys
|
|
25
|
+
* from Left/Right to Up/Down, per WAI-ARIA APG. Left/Right invert under RTL.
|
|
26
|
+
*
|
|
27
|
+
* Events (bubbling, from the tablist): `fw:tabs-change` { tab, panel }.
|
|
28
|
+
*/
|
|
29
|
+
export type TabsActivation = 'automatic' | 'manual';
|
|
30
|
+
export interface TabsOptions {
|
|
31
|
+
activation?: TabsActivation;
|
|
32
|
+
}
|
|
33
|
+
export interface TabsInstance {
|
|
34
|
+
activate(tab: HTMLElement, focus?: boolean): void;
|
|
35
|
+
destroy(): void;
|
|
36
|
+
}
|
|
37
|
+
export interface TabsChangeDetail {
|
|
38
|
+
tab: HTMLElement;
|
|
39
|
+
panel: HTMLElement;
|
|
40
|
+
}
|
|
41
|
+
export declare function tabs(tablist: HTMLElement, opts?: TabsOptions): TabsInstance;
|
|
42
|
+
/** Wire every `[role="tablist"][data-fw-tabs]` under `root`. */
|
|
43
|
+
export declare function init(root?: ParentNode): void;
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme — toggles `data-theme="dark"` on <html>, remembers the choice, and
|
|
3
|
-
* falls back to the OS preference. Also carries the runtime token API
|
|
4
|
-
* (`setTokens` / `resetTokens` / `getToken`) for retheming Fernwell's colour
|
|
5
|
-
* tokens on the fly — per-tenant branding, a user-picked accent, a live
|
|
6
|
-
* preview — without touching a stylesheet.
|
|
7
|
-
*
|
|
8
|
-
* <button class="fw-btn fw-btn-ghost" data-fw-theme-toggle
|
|
9
|
-
* data-fw-theme-label-dark="☀️ Light" data-fw-theme-label-light="🌙 Dark">🌙 Dark</button>
|
|
10
|
-
*
|
|
11
|
-
* To avoid a flash of the wrong theme on load, inline this before your CSS:
|
|
12
|
-
* <script>document.documentElement.dataset.theme=localStorage.getItem('fw-theme')||(matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light')</script>
|
|
13
|
-
*/
|
|
14
1
|
export type Theme = 'light' | 'dark';
|
|
15
2
|
/** The theme currently applied to <html>, or the system preference if none is set. */
|
|
16
3
|
export declare function get(): Theme;
|
package/dist/tokens.json
CHANGED
|
@@ -130,6 +130,18 @@
|
|
|
130
130
|
"focus-ring": {
|
|
131
131
|
"value": "0 0 0 4px color-mix(in srgb, {primary} 25%, transparent)",
|
|
132
132
|
"comment": "derived: box-shadow focus ring, primary wash"
|
|
133
|
+
},
|
|
134
|
+
"scrollbar-thumb": {
|
|
135
|
+
"value": "{text-soft}",
|
|
136
|
+
"comment": "scrollbar thumb — reuses secondary-text so it recedes against content"
|
|
137
|
+
},
|
|
138
|
+
"scrollbar-thumb-hover": {
|
|
139
|
+
"value": "color-mix(in srgb, {text-soft}, {text} 15%)",
|
|
140
|
+
"comment": "derived: darkens toward full-strength text on hover, same recipe as secondary-hover"
|
|
141
|
+
},
|
|
142
|
+
"scrollbar-track": {
|
|
143
|
+
"value": "transparent",
|
|
144
|
+
"comment": "default track; Table overrides to bg-dim so its scrollbar reads as clearly present"
|
|
133
145
|
}
|
|
134
146
|
},
|
|
135
147
|
"font": {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tooltip — a short hover/focus annotation, anchored to its trigger.
|
|
3
|
+
*
|
|
4
|
+
* <button type="button" class="fw-icon-btn" title="Copy to clipboard" data-fw-tooltip>
|
|
5
|
+
* <span data-fw-icon="copy" aria-hidden="true"></span>
|
|
6
|
+
* </button>
|
|
7
|
+
*
|
|
8
|
+
* The `title` attribute is the content source — it's moved into
|
|
9
|
+
* `dataset.fwTooltipText` and removed on init (same detach-and-mirror trick
|
|
10
|
+
* combobox.ts uses for the `list` attribute), which gives a real no-JS
|
|
11
|
+
* fallback (the native OS tooltip) and stops the two tooltips firing at once.
|
|
12
|
+
*
|
|
13
|
+
* Optional trigger attributes: `data-fw-tooltip-placement` (default "top";
|
|
14
|
+
* also accepts "bottom" | "left" | "right", or a corner variant —
|
|
15
|
+
* "top-left" | "top-right" | "bottom-left" | "bottom-right" — that leans the
|
|
16
|
+
* bubble toward that corner instead of centering it, for triggers near a
|
|
17
|
+
* layout edge), `data-fw-tooltip-offset` (px, default 6),
|
|
18
|
+
* `data-fw-tooltip-delay` (ms, default 400).
|
|
19
|
+
*
|
|
20
|
+
* The bubble is centered on the trigger by default so the arrow (drawn at
|
|
21
|
+
* `computePosition`'s returned `arrowOffset`) always points at the trigger's
|
|
22
|
+
* midpoint — including when a corner placement or a viewport-edge clamp
|
|
23
|
+
* shifts the bubble off-center.
|
|
24
|
+
*
|
|
25
|
+
* Only one tooltip bubble exists for the whole page (a lazily-created
|
|
26
|
+
* singleton, same pattern as toast.ts) — a second trigger's hover pre-empts
|
|
27
|
+
* the first. Acceptable for a short annotation; not meant for concurrent
|
|
28
|
+
* multi-tooltip UIs.
|
|
29
|
+
*
|
|
30
|
+
* WCAG 2.1 SC 1.4.13 requires hover/focus-revealed content to be dismissible,
|
|
31
|
+
* *hoverable* (the pointer can move onto it without it disappearing) and
|
|
32
|
+
* persistent. `pointer-events: none` on the bubble would fail "hoverable"
|
|
33
|
+
* outright — the bubble couldn't receive a hover at all — so this
|
|
34
|
+
* deliberately does NOT set it while open. Instead the bubble gets its own
|
|
35
|
+
* mouseenter/mouseleave, and a short cancelable hide-grace timer covers the
|
|
36
|
+
* gap while the pointer travels from trigger to bubble.
|
|
37
|
+
*/
|
|
38
|
+
import { type Placement } from './_position';
|
|
39
|
+
export interface TooltipOptions {
|
|
40
|
+
placement?: Placement;
|
|
41
|
+
offset?: number;
|
|
42
|
+
delay?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface TooltipInstance {
|
|
45
|
+
show(): void;
|
|
46
|
+
hide(): void;
|
|
47
|
+
destroy(): void;
|
|
48
|
+
}
|
|
49
|
+
export declare function tooltip(trigger: HTMLElement, opts?: TooltipOptions): TooltipInstance;
|
|
50
|
+
/** Wire every `[data-fw-tooltip]` under `root`. */
|
|
51
|
+
export declare function init(root?: ParentNode): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fernwell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Fernwell — the HunnyDo design system. Design tokens, CSS components, and small vanilla JS enhancers that work in any web app, with or without a build step.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,10 +44,12 @@
|
|
|
44
44
|
"./package.json": "./package.json"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|
|
47
|
-
"dev": "
|
|
47
|
+
"dev": "node scripts/dev.mjs",
|
|
48
48
|
"tokens": "node scripts/gen-tokens.mjs",
|
|
49
49
|
"lint": "node scripts/lint-tokens.mjs",
|
|
50
|
-
"
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"build": "npm run tokens && npm run lint && node scripts/build.mjs && tsc -p tsconfig.build.json",
|
|
51
53
|
"docs": "serve docs/",
|
|
52
54
|
"prepublishOnly": "npm run build"
|
|
53
55
|
},
|
|
@@ -55,8 +57,11 @@
|
|
|
55
57
|
"node": ">=18"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
58
|
-
"
|
|
60
|
+
"@testing-library/dom": "^10.4.2",
|
|
61
|
+
"esbuild": "^0.28.2",
|
|
62
|
+
"jsdom": "^29.1.1",
|
|
59
63
|
"serve": "^14.2.6",
|
|
60
|
-
"typescript": "^5.9.3"
|
|
64
|
+
"typescript": "^5.9.3",
|
|
65
|
+
"vitest": "^5.0.1"
|
|
61
66
|
}
|
|
62
67
|
}
|