@putdotio/design 3.7.0 → 3.8.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/DESIGN.md +19 -7
- package/dist/css/tokens.css +3 -1
- package/dist/figma/putio.tokens.json +4 -0
- package/dist/tokens.d.ts +1 -1
- package/dist/tokens.dtcg.json +26 -2
- package/dist/tokens.flat.json +19 -3
- package/dist/tokens.js +19 -3
- package/package.json +1 -1
- package/system/README.md +3 -5
- package/system/components.css +155 -11
- package/tokens/primitives.tokens.json +26 -2
package/DESIGN.md
CHANGED
|
@@ -115,7 +115,8 @@ Default radius `6px`; `4px` for tight controls, `8px` or `10px` for panels, pill
|
|
|
115
115
|
- **Primary:** `--button-primary-bg`, hover `--button-primary-bg-hover`, label `--button-primary-fg`. At most one per action group.
|
|
116
116
|
- **Secondary:** `--button-default-bg` plus a `--border` border; hover steps both (`--button-default-bg-hover`, `--border-hover`).
|
|
117
117
|
- **Ghost:** text only, `--button-ghost-fg`; hover adds `--button-ghost-bg-hover` and lifts the label to `--button-ghost-fg-hover`. Use it for anything quieter than secondary: header `Sign in`, toolbar actions, `Cancel` beside a confirm, icon-only buttons.
|
|
118
|
-
- **Disabled:** colour drops to `--solid` at full opacity.
|
|
118
|
+
- **Disabled:** colour drops to `--solid` at full opacity: filled variants take a `--solid` fill with `--solid-foreground` labels; quiet ones take `--solid` text. A finished action stays filled with `data-state="success"` on `.btn-success`.
|
|
119
|
+
- **Focus:** `--shadow-focus`, a 2px `--bg` gap then a 2px `--solid-hover` ring, at least 3:1 against the page and panels in both modes.
|
|
119
120
|
- A bordered button always fills (secondary). Border-only buttons read smaller beside solid fills and vanish on dark.
|
|
120
121
|
- Four sizes share one box per size across tiers: default 36px, `md` 32px, `sm` 28px, `xs` 24px. Read `--button-height*`, `--button-padding-x*`, `--button-label-size*`, `--button-tracking*`, `--button-icon-size`, `--button-gap`.
|
|
121
122
|
- A dark bar on a light page is a `.dark`-scoped region.
|
|
@@ -128,15 +129,26 @@ Default radius `6px`; `4px` for tight controls, `8px` or `10px` for panels, pill
|
|
|
128
129
|
- Fields read `--field-bg`, `--field-border`, and `--field-ring` (focus). `aria-invalid="true"` turns border and text red; the fill stays.
|
|
129
130
|
- Raised panels read `--panel-*`.
|
|
130
131
|
- Feedback uses `.form-callout`: `--alert-*` colours, `data-state` `info`, `success`, or `error`; `.inline` drops surface and border. It holds a message only. `.form-group` (`6px` gap) spaces a control and its feedback.
|
|
132
|
+
- Every field and form error eases in through `.form-reveal`: `grid-template-rows` `0fr` to `1fr` plus opacity, over `--dur-reveal` (`180ms`) with `--ease-out`, so whatever sits below slides instead of jumping. A field error sits under its field inside `.form-group`, where the row absorbs the group gap; a form error sits above the submit button. `data-state="open"` shows it. Keep the `role="alert"` message mounted and rendered; empty it once a closed row has collapsed. An `aria-invalid` field or code fades its border red over the same `--dur-reveal`. Under `prefers-reduced-motion` nothing animates.
|
|
131
133
|
|
|
132
134
|
### Auth
|
|
133
135
|
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
136
|
+
- Sign in, sign up, password reset, and two-factor pages have no card or panel: the form sits on `--bg`. Recipe: `.auth-page`, `.auth-header`, `.auth-main`, `.auth-column`, `.auth-title`, `.auth-links`, `.auth-footer`.
|
|
137
|
+
- The logo sits top-left in the header, in a `30.33px` box (26px ink × 7/6). The top right stays empty by default.
|
|
138
|
+
- One left-aligned column, up to `340px`, is centred horizontally and vertically.
|
|
139
|
+
- A quiet centred footer links Terms of Service, Privacy Policy, and Help in muted `--fs-sm`.
|
|
140
|
+
- One title per screen: `22px`, medium, `-0.01em` tracking. No subtitles, taglines, or marketing lines; copy stays short.
|
|
141
|
+
- Fields are filled: the page points `--field-bg` at `--bg-secondary` and `--field-border` at `--line`. Fields and buttons in the column are `44px`.
|
|
142
|
+
- Labels are small, muted, and above the field.
|
|
143
|
+
- The primary button is full-width yellow. Secondary actions sit under the form as muted text links: “Forgot password?”, “New to put.io? Sign up”, “Wrong account? Sign out”.
|
|
144
|
+
- Tab order runs fields, submit, then secondary links; DOM order follows visual order, with no positive `tabindex`. Two-factor runs the code, Verify, then its links. The reveal-password toggle takes `tabindex="-1"` and keeps its accessible name: keyboard-only users can't toggle visibility, screen-reader users still can in browse mode. No link leaves the tab order.
|
|
145
|
+
- Form errors: one message in a `.form-reveal` row right above the submit button, in red `--fs-base` text. Invalid fields turn red. Auth forms never use the boxed `.form-callout`.
|
|
146
|
+
- Copy: “Sign in”, “Sign up”, and “That username or password doesn't look right.”
|
|
147
|
+
- auth.put.io still ships the older card layout: drift.
|
|
148
|
+
- References: `web-s06-auth`, `web-p00c-auth-signin`, `web-p00d-auth-signup`, `web-p00e-auth-2fa`. Outside references: the TIDAL, Stripe Link, Cursor, Linear, and Vercel sign-in pages.
|
|
149
|
+
- One-time codes are one `.otp-input` (`inputmode="numeric"`, `autocomplete="one-time-code"`, `maxlength="6"`, `aria-invalid`) shown through two `.otp-group`s, one `.otp-separator`, and six `.otp-slot`s; script syncs slot text and `filled`/`active`, and maps a clicked slot to the input selection. The slots stretch the full column with mono digits. The label reads “Code from your authenticator app”, with no hint line.
|
|
150
|
+
- Editing an invalid code closes the error; retry waits for six digits. `data-state="verifying"` disables the input, keeps the digits, and announces through a polite live region. `data-state="success"` keeps the digits read-only, announces continuation in a `role="status"` region, and shows no further action; the consumer owns navigation. The submit turns a disabled `.btn-success` with `data-state="success"`, relabelled “Verified”, announced through a visually hidden status region.
|
|
151
|
+
- “Use a recovery code” appears only once a consumer owns the route. Groups own the responsive width, so the control fits narrow columns without scrolling.
|
|
140
152
|
|
|
141
153
|
### TV
|
|
142
154
|
|
package/dist/css/tokens.css
CHANGED
|
@@ -172,6 +172,7 @@
|
|
|
172
172
|
--yellow-text-secondary: hsl(46, 100%, 27%);
|
|
173
173
|
--yellow-text: hsl(43, 32%, 21%);
|
|
174
174
|
--lime-3: hsl(85, 76.0%, 92.3%);
|
|
175
|
+
--shadow-focus: 0 0 0 2px hsl(0, 0%, 99.0%), 0 0 0 4px hsl(0, 0%, 52.3%);
|
|
175
176
|
--html-bg: hsl(0, 0%, 97.3%);
|
|
176
177
|
--app-bg: hsl(0, 0%, 100%);
|
|
177
178
|
--nav-bg: hsl(0, 0%, 100%);
|
|
@@ -256,7 +257,6 @@
|
|
|
256
257
|
--shadow-md: 0 4px 12px hsla(0, 0%, 0%, 0.08);
|
|
257
258
|
--shadow-lg: 0 16px 40px hsla(0, 0%, 0%, 0.12);
|
|
258
259
|
--shadow-focus-color: hsla(47, 100%, 65%, 0.35);
|
|
259
|
-
--shadow-focus: 0 0 0 3px hsla(47, 100%, 65%, 0.35);
|
|
260
260
|
--font-sans: "GT America", sans-serif;
|
|
261
261
|
--font-display: "GT America", sans-serif;
|
|
262
262
|
--font-mono: "Berkeley Mono", monospace;
|
|
@@ -301,6 +301,7 @@
|
|
|
301
301
|
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
302
302
|
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
|
|
303
303
|
--dur-fast: 120ms;
|
|
304
|
+
--dur-reveal: 180ms;
|
|
304
305
|
--dur-base: 200ms;
|
|
305
306
|
--dur-slow: 320ms;
|
|
306
307
|
--z-dropdown: 1000;
|
|
@@ -479,6 +480,7 @@
|
|
|
479
480
|
--yellow-text-secondary: hsl(45, 100%, 64%);
|
|
480
481
|
--yellow-text: hsl(46, 89%, 86%);
|
|
481
482
|
--lime-3: hsl(85, 45%, 12%);
|
|
483
|
+
--shadow-focus: 0 0 0 2px hsl(0, 0%, 8.5%), 0 0 0 4px hsl(0, 0%, 49.4%);
|
|
482
484
|
--html-bg: hsl(0, 0%, 0%);
|
|
483
485
|
--app-bg: hsl(0, 0%, 8.5%);
|
|
484
486
|
--nav-bg: hsl(0, 0%, 8.5%);
|
package/dist/tokens.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Do not edit directly. Generated from tokens/**/*.tokens.json.
|
|
2
2
|
|
|
3
|
-
export type PutioTokenName = "component.button.primary.background" | "component.button.primary.backgroundHover" | "component.button.primary.backgroundHoverDark" | "component.button.primary.foreground" | "component.button.primary.radius" | "component.button.secondary.background" | "component.button.secondary.backgroundDark" | "component.button.secondary.foreground" | "component.button.secondary.foregroundDark" | "component.button.secondary.backgroundHover" | "component.button.secondary.backgroundHoverDark" | "component.button.success.background" | "component.button.success.backgroundDark" | "component.button.success.backgroundHover" | "component.button.success.backgroundHoverDark" | "component.button.success.foreground" | "component.button.danger.background" | "component.button.danger.backgroundDark" | "component.button.danger.backgroundHover" | "component.button.danger.backgroundHoverDark" | "component.button.danger.foreground" | "component.button.info.background" | "component.button.info.backgroundDark" | "component.button.info.backgroundHover" | "component.button.info.backgroundHoverDark" | "component.button.info.foreground" | "component.button.info.foregroundDark" | "component.button.default.background" | "component.button.default.backgroundDark" | "component.button.default.backgroundHover" | "component.button.default.backgroundHoverDark" | "component.button.default.foreground" | "component.button.default.foregroundDark" | "component.button.ghost.background" | "component.button.ghost.foreground" | "component.button.ghost.foregroundDark" | "component.button.ghost.foregroundHover" | "component.button.ghost.foregroundHoverDark" | "component.button.ghost.backgroundHover" | "component.button.ghost.backgroundHoverDark" | "component.button.height" | "component.button.heightMd" | "component.button.heightSm" | "component.button.heightXs" | "component.button.paddingX" | "component.button.paddingXXs" | "component.button.labelSize" | "component.button.labelSizeXs" | "component.button.tracking" | "component.button.trackingMd" | "component.button.trackingSm" | "component.button.trackingXs" | "component.button.iconSize" | "component.button.gap" | "component.nav.height" | "component.nav.heightCompact" | "component.nav.ctaHeight" | "component.input.background" | "component.input.backgroundDark" | "component.input.border" | "component.input.borderDark" | "component.input.radius" | "component.input.borderHover" | "component.input.borderHoverDark" | "component.input.borderFocus" | "component.input.borderFocusDark" | "component.input.ring" | "component.input.ringDark" | "component.input.text" | "component.input.textDark" | "component.input.placeholder" | "component.input.placeholderDark" | "component.field.background" | "component.field.backgroundDark" | "component.field.backgroundDisabled" | "component.field.backgroundDisabledDark" | "component.field.border" | "component.field.borderDark" | "component.field.borderHover" | "component.field.borderHoverDark" | "component.field.borderFocus" | "component.field.borderFocusDark" | "component.field.text" | "component.field.textDark" | "component.field.placeholder" | "component.field.placeholderDark" | "component.field.radius" | "component.field.ring" | "component.field.ringDark" | "component.panel.background" | "component.panel.backgroundDark" | "component.panel.border" | "component.panel.borderDark" | "component.panel.radius" | "component.panel.shadow" | "component.panel.shadowDark" | "component.alias.background" | "component.alias.backgroundDark" | "component.alias.foreground" | "component.alias.foregroundDark" | "component.alias.foregroundMuted" | "component.alias.foregroundMutedDark" | "component.alias.primary" | "component.alias.primaryForeground" | "component.alias.success" | "component.alias.successDark" | "component.alias.successForeground" | "component.alias.destructive" | "component.alias.destructiveDark" | "component.alias.destructiveForeground" | "component.alias.invertForeground" | "component.alias.invertForegroundDark" | "component.alias.solidForeground" | "component.alias.solidForegroundDark" | "component.alias.muted" | "component.alias.mutedDark" | "component.alias.mutedForeground" | "component.alias.mutedForegroundDark" | "component.alias.accent" | "component.alias.accentDark" | "component.alias.accentForeground" | "component.alias.accentForegroundDark" | "component.alias.card" | "component.alias.cardDark" | "component.alias.cardForeground" | "component.alias.cardForegroundDark" | "component.alias.popover" | "component.alias.popoverDark" | "component.alias.popoverForeground" | "component.alias.popoverForegroundDark" | "component.alias.input" | "component.alias.inputDark" | "component.alias.ring" | "component.fileRow.background" | "component.fileRow.backgroundDark" | "component.fileRow.hoverBackground" | "component.fileRow.hoverBackgroundDark" | "component.fileRow.activeBackground" | "component.fileRow.activeBackgroundDark" | "component.fileRow.border" | "component.fileRow.borderDark" | "component.fileRow.icon" | "component.notification.infoBackground" | "component.notification.infoBackgroundDark" | "component.notification.dangerBackground" | "component.notification.dangerBackgroundDark" | "component.notification.background" | "component.notification.backgroundDark" | "component.notification.border" | "component.notification.borderDark" | "component.notification.foreground" | "component.notification.foregroundDark" | "component.notification.icon" | "component.notification.iconDark" | "component.notification.successBackground" | "component.notification.successBackgroundDark" | "component.notification.successBorder" | "component.notification.successBorderDark" | "component.notification.successForeground" | "component.notification.successForegroundDark" | "component.notification.dangerBorder" | "component.notification.dangerBorderDark" | "component.notification.dangerForeground" | "component.notification.dangerForegroundDark" | "component.notification.badgeBackground" | "component.notification.badgeForeground" | "component.menu.background" | "component.menu.backgroundDark" | "component.menu.border" | "component.menu.borderDark" | "component.menu.radius" | "component.menu.shadow" | "component.menu.shadowDark" | "component.menu.itemBackgroundHover" | "component.menu.itemBackgroundHoverDark" | "component.menu.itemText" | "component.menu.itemTextDark" | "component.menu.itemIcon" | "component.menu.itemIconDark" | "component.menu.itemShortcut" | "component.menu.itemShortcutDark" | "component.menu.itemDangerText" | "component.menu.itemDangerTextDark" | "component.menu.itemDangerBackgroundHover" | "component.menu.itemDangerBackgroundHoverDark" | "component.menu.itemHeight" | "component.menu.separator" | "component.menu.separatorDark" | "component.menu.label" | "component.menu.labelDark" | "component.palette.background" | "component.palette.backgroundDark" | "component.palette.border" | "component.palette.borderDark" | "component.palette.shadow" | "component.palette.shadowDark" | "component.palette.scrim" | "component.palette.scrimDark" | "component.palette.width" | "component.palette.inputHeight" | "component.palette.itemHeight" | "component.palette.itemBackgroundActive" | "component.palette.itemBackgroundActiveDark" | "component.palette.groupLabel" | "component.palette.groupLabelDark" | "component.palette.itemMeta" | "component.palette.itemMetaDark" | "component.sheet.background" | "component.sheet.backgroundDark" | "component.sheet.border" | "component.sheet.borderDark" | "component.sheet.shadow" | "component.sheet.shadowDark" | "component.sheet.scrim" | "component.sheet.scrimDark" | "component.sheet.width" | "component.avatar.yellow" | "component.avatar.green" | "component.avatar.red" | "component.avatar.blue" | "component.avatar.purple" | "component.avatar.teal" | "component.avatar.orange" | "component.avatar.foreground" | "component.avatar.foregroundWarm" | "component.alert.radius" | "component.alert.infoBackground" | "component.alert.infoBackgroundDark" | "component.alert.infoBorder" | "component.alert.infoBorderDark" | "component.alert.infoText" | "component.alert.infoTextDark" | "component.alert.infoBody" | "component.alert.infoBodyDark" | "component.alert.infoIcon" | "component.alert.infoIconDark" | "component.alert.brandBackground" | "component.alert.brandBackgroundDark" | "component.alert.brandBorder" | "component.alert.brandBorderDark" | "component.alert.brandText" | "component.alert.brandTextDark" | "component.alert.brandBody" | "component.alert.brandBodyDark" | "component.alert.brandIcon" | "component.alert.brandIconDark" | "component.alert.successBackground" | "component.alert.successBackgroundDark" | "component.alert.successBorder" | "component.alert.successBorderDark" | "component.alert.successText" | "component.alert.successTextDark" | "component.alert.successBody" | "component.alert.successBodyDark" | "component.alert.successIcon" | "component.alert.successIconDark" | "component.alert.dangerBackground" | "component.alert.dangerBackgroundDark" | "component.alert.dangerBorder" | "component.alert.dangerBorderDark" | "component.alert.dangerText" | "component.alert.dangerTextDark" | "component.alert.dangerBody" | "component.alert.dangerBodyDark" | "component.alert.dangerIcon" | "component.alert.dangerIconDark" | "component.slider.track" | "component.slider.trackDark" | "component.slider.buffer" | "component.slider.bufferDark" | "component.slider.fill" | "component.slider.knob" | "component.slider.fillDisabled" | "component.slider.fillDisabledDark" | "component.slider.trackHeight" | "component.slider.knobSize" | "component.slider.hitHeight" | "component.pagination.itemSize" | "component.pagination.itemText" | "component.pagination.itemTextDark" | "component.pagination.itemTextActive" | "component.pagination.itemTextActiveDark" | "component.pagination.itemBackgroundHover" | "component.pagination.itemBackgroundHoverDark" | "component.pagination.itemBackgroundActive" | "component.pagination.itemBackgroundActiveDark" | "component.pagination.itemBorderActive" | "component.pagination.itemBorderActiveDark" | "context.tv.text.primary" | "context.tv.text.secondary" | "context.tv.text.tertiary" | "context.tv.channelArt.production.posterBackground" | "context.tv.channelArt.production.splashBackground" | "context.tv.channelArt.development.background" | "context.tv.channelArt.development.accent" | "context.tv.channelArt.development.grid" | "context.tv.channelArt.nightly.background" | "context.tv.channelArt.nightly.accent" | "context.tv.channelArt.nightly.star" | "context.tv.channelArt.nightly.moon" | "context.tv.channelArt.nightly.moonCrater" | "context.tv.channelArt.lab.background" | "context.tv.channelArt.lab.foreground" | "context.tv.channelArt.lab.accent" | "tv.video.background" | "tv.video.heroScrimTop" | "tv.video.heroScrimBottom" | "tv.video.textOnVideo" | "tv.text.heading" | "tv.text.label" | "tv.text.body" | "tv.text.caption" | "tv.text.smol" | "tv.fontWeight.regular" | "tv.fontWeight.medium" | "tv.space.xxs" | "tv.space.xs" | "tv.space.sm" | "tv.space.md" | "tv.space.lg" | "tv.space.xl" | "tv.space.xxl" | "tv.overscan.x" | "tv.overscan.y" | "tv.radius" | "tv.focus.borderWidth" | "tv.focus.row.background" | "tv.focus.row.backgroundFocused" | "tv.focus.control.background" | "tv.focus.control.backgroundFocused" | "tv.focus.control.border" | "tv.focus.control.borderFocused" | "tv.z.modal" | "tv.z.toast" | "tv.z.overlay" | "color.brand.yellow" | "color.neutral.light.bg" | "color.neutral.light.bgSecondary" | "color.neutral.light.componentBg" | "color.neutral.light.componentBgHover" | "color.neutral.light.componentBgActive" | "color.neutral.light.line" | "color.neutral.light.border" | "color.neutral.light.borderHover" | "color.neutral.light.solid" | "color.neutral.light.solidHover" | "color.neutral.light.textSecondary" | "color.neutral.light.text" | "color.neutral.dark.bg" | "color.neutral.dark.bgSecondary" | "color.neutral.dark.componentBg" | "color.neutral.dark.componentBgHover" | "color.neutral.dark.componentBgActive" | "color.neutral.dark.line" | "color.neutral.dark.border" | "color.neutral.dark.borderHover" | "color.neutral.dark.solid" | "color.neutral.dark.solidHover" | "color.neutral.dark.textSecondary" | "color.neutral.dark.text" | "color.green.light.bg" | "color.green.light.bgSecondary" | "color.green.light.componentBg" | "color.green.light.componentBgHover" | "color.green.light.componentBgActive" | "color.green.light.line" | "color.green.light.border" | "color.green.light.borderHover" | "color.green.light.solid" | "color.green.light.solidHover" | "color.green.light.textSecondary" | "color.green.light.text" | "color.green.dark.bg" | "color.green.dark.bgSecondary" | "color.green.dark.componentBg" | "color.green.dark.componentBgHover" | "color.green.dark.componentBgActive" | "color.green.dark.line" | "color.green.dark.border" | "color.green.dark.borderHover" | "color.green.dark.solid" | "color.green.dark.solidHover" | "color.green.dark.textSecondary" | "color.green.dark.text" | "color.red.light.bg" | "color.red.light.bgSecondary" | "color.red.light.componentBg" | "color.red.light.componentBgHover" | "color.red.light.componentBgActive" | "color.red.light.line" | "color.red.light.border" | "color.red.light.borderHover" | "color.red.light.solid" | "color.red.light.solidHover" | "color.red.light.textSecondary" | "color.red.light.text" | "color.red.dark.bg" | "color.red.dark.bgSecondary" | "color.red.dark.componentBg" | "color.red.dark.componentBgHover" | "color.red.dark.componentBgActive" | "color.red.dark.line" | "color.red.dark.border" | "color.red.dark.borderHover" | "color.red.dark.solid" | "color.red.dark.solidHover" | "color.red.dark.textSecondary" | "color.red.dark.text" | "color.yellow.light.bg" | "color.yellow.light.bgSecondary" | "color.yellow.light.componentBg" | "color.yellow.light.componentBgHover" | "color.yellow.light.componentBgActive" | "color.yellow.light.line" | "color.yellow.light.border" | "color.yellow.light.borderHover" | "color.yellow.light.solidHover" | "color.yellow.light.textSecondary" | "color.yellow.light.text" | "color.yellow.dark.bg" | "color.yellow.dark.bgSecondary" | "color.yellow.dark.componentBg" | "color.yellow.dark.componentBgHover" | "color.yellow.dark.componentBgActive" | "color.yellow.dark.line" | "color.yellow.dark.border" | "color.yellow.dark.borderHover" | "color.yellow.dark.solidHover" | "color.yellow.dark.textSecondary" | "color.yellow.dark.text" | "color.transfer.light.lime3" | "color.transfer.dark.lime3" | "elevation.shadowColor" | "elevation.color" | "elevation.sm" | "elevation.md" | "elevation.lg" | "elevation.focusColor" | "elevation.focus" | "typography.fontFamily.sans" | "typography.fontFamily.display" | "typography.fontFamily.mono" | "typography.fontSize.xs" | "typography.fontSize.sm" | "typography.fontSize.base" | "typography.fontSize.md" | "typography.fontSize.lg" | "typography.fontSize.xl" | "typography.fontSize.2xl" | "typography.fontSize.3xl" | "typography.fontSize.4xl" | "typography.fontSize.display" | "typography.lineHeight.tight" | "typography.lineHeight.snug" | "typography.lineHeight.normal" | "typography.lineHeight.loose" | "typography.fontWeight.regular" | "typography.fontWeight.medium" | "typography.fontWeight.bold" | "typography.fontWeight.black" | "typography.letterSpacing.tight" | "typography.letterSpacing.normal" | "typography.letterSpacing.wide" | "typography.letterSpacing.uppercase" | "spacing.0" | "spacing.1" | "spacing.2" | "spacing.3" | "spacing.4" | "spacing.5" | "spacing.6" | "spacing.7" | "spacing.8" | "radius.sm" | "radius.default" | "radius.md" | "radius.lg" | "radius.pill" | "radius.tv" | "border.width" | "motion.easing.out" | "motion.easing.inOut" | "motion.duration.fast" | "motion.duration.base" | "motion.duration.slow" | "z.dropdown" | "z.sticky" | "z.modal" | "z.notification" | "z.tooltip" | "breakpoint.sm" | "breakpoint.md" | "breakpoint.lg" | "surface.light.htmlBg" | "surface.light.appBg" | "surface.light.navBg" | "surface.light.navItemBg" | "surface.light.navItemBgHover" | "surface.light.navItemBgActive" | "surface.light.listItemBg" | "surface.light.listItemBgHover" | "surface.light.listItemBgActive" | "surface.light.listItemBorder" | "surface.light.segmentedControlBg" | "surface.light.segmentedControlBgActive" | "surface.light.transferListItemCompletingBg" | "surface.light.transferListItemDownloadingBg" | "surface.light.transferListItemFinishedBg" | "surface.light.transferListItemPassiveBg" | "surface.light.hiContrast" | "surface.light.loContrast" | "surface.light.transparent" | "surface.light.overlayInline" | "surface.light.overlayFull" | "surface.dark.htmlBg" | "surface.dark.appBg" | "surface.dark.navBg" | "surface.dark.navItemBg" | "surface.dark.navItemBgHover" | "surface.dark.navItemBgActive" | "surface.dark.listItemBg" | "surface.dark.listItemBgHover" | "surface.dark.listItemBgActive" | "surface.dark.listItemBorder" | "surface.dark.segmentedControlBg" | "surface.dark.segmentedControlBgActive" | "surface.dark.transferListItemCompletingBg" | "surface.dark.transferListItemDownloadingBg" | "surface.dark.transferListItemFinishedBg" | "surface.dark.transferListItemPassiveBg" | "surface.dark.hiContrast" | "surface.dark.loContrast" | "surface.dark.overlayInline" | "surface.dark.overlayFull" | "surface.dark.shadowColor" | "surface.dark.shadow" | "surface.dark.shadowSm" | "surface.dark.shadowMd" | "surface.dark.shadowLg";
|
|
3
|
+
export type PutioTokenName = "component.button.primary.background" | "component.button.primary.backgroundHover" | "component.button.primary.backgroundHoverDark" | "component.button.primary.foreground" | "component.button.primary.radius" | "component.button.secondary.background" | "component.button.secondary.backgroundDark" | "component.button.secondary.foreground" | "component.button.secondary.foregroundDark" | "component.button.secondary.backgroundHover" | "component.button.secondary.backgroundHoverDark" | "component.button.success.background" | "component.button.success.backgroundDark" | "component.button.success.backgroundHover" | "component.button.success.backgroundHoverDark" | "component.button.success.foreground" | "component.button.danger.background" | "component.button.danger.backgroundDark" | "component.button.danger.backgroundHover" | "component.button.danger.backgroundHoverDark" | "component.button.danger.foreground" | "component.button.info.background" | "component.button.info.backgroundDark" | "component.button.info.backgroundHover" | "component.button.info.backgroundHoverDark" | "component.button.info.foreground" | "component.button.info.foregroundDark" | "component.button.default.background" | "component.button.default.backgroundDark" | "component.button.default.backgroundHover" | "component.button.default.backgroundHoverDark" | "component.button.default.foreground" | "component.button.default.foregroundDark" | "component.button.ghost.background" | "component.button.ghost.foreground" | "component.button.ghost.foregroundDark" | "component.button.ghost.foregroundHover" | "component.button.ghost.foregroundHoverDark" | "component.button.ghost.backgroundHover" | "component.button.ghost.backgroundHoverDark" | "component.button.height" | "component.button.heightMd" | "component.button.heightSm" | "component.button.heightXs" | "component.button.paddingX" | "component.button.paddingXXs" | "component.button.labelSize" | "component.button.labelSizeXs" | "component.button.tracking" | "component.button.trackingMd" | "component.button.trackingSm" | "component.button.trackingXs" | "component.button.iconSize" | "component.button.gap" | "component.nav.height" | "component.nav.heightCompact" | "component.nav.ctaHeight" | "component.input.background" | "component.input.backgroundDark" | "component.input.border" | "component.input.borderDark" | "component.input.radius" | "component.input.borderHover" | "component.input.borderHoverDark" | "component.input.borderFocus" | "component.input.borderFocusDark" | "component.input.ring" | "component.input.ringDark" | "component.input.text" | "component.input.textDark" | "component.input.placeholder" | "component.input.placeholderDark" | "component.field.background" | "component.field.backgroundDark" | "component.field.backgroundDisabled" | "component.field.backgroundDisabledDark" | "component.field.border" | "component.field.borderDark" | "component.field.borderHover" | "component.field.borderHoverDark" | "component.field.borderFocus" | "component.field.borderFocusDark" | "component.field.text" | "component.field.textDark" | "component.field.placeholder" | "component.field.placeholderDark" | "component.field.radius" | "component.field.ring" | "component.field.ringDark" | "component.panel.background" | "component.panel.backgroundDark" | "component.panel.border" | "component.panel.borderDark" | "component.panel.radius" | "component.panel.shadow" | "component.panel.shadowDark" | "component.alias.background" | "component.alias.backgroundDark" | "component.alias.foreground" | "component.alias.foregroundDark" | "component.alias.foregroundMuted" | "component.alias.foregroundMutedDark" | "component.alias.primary" | "component.alias.primaryForeground" | "component.alias.success" | "component.alias.successDark" | "component.alias.successForeground" | "component.alias.destructive" | "component.alias.destructiveDark" | "component.alias.destructiveForeground" | "component.alias.invertForeground" | "component.alias.invertForegroundDark" | "component.alias.solidForeground" | "component.alias.solidForegroundDark" | "component.alias.muted" | "component.alias.mutedDark" | "component.alias.mutedForeground" | "component.alias.mutedForegroundDark" | "component.alias.accent" | "component.alias.accentDark" | "component.alias.accentForeground" | "component.alias.accentForegroundDark" | "component.alias.card" | "component.alias.cardDark" | "component.alias.cardForeground" | "component.alias.cardForegroundDark" | "component.alias.popover" | "component.alias.popoverDark" | "component.alias.popoverForeground" | "component.alias.popoverForegroundDark" | "component.alias.input" | "component.alias.inputDark" | "component.alias.ring" | "component.fileRow.background" | "component.fileRow.backgroundDark" | "component.fileRow.hoverBackground" | "component.fileRow.hoverBackgroundDark" | "component.fileRow.activeBackground" | "component.fileRow.activeBackgroundDark" | "component.fileRow.border" | "component.fileRow.borderDark" | "component.fileRow.icon" | "component.notification.infoBackground" | "component.notification.infoBackgroundDark" | "component.notification.dangerBackground" | "component.notification.dangerBackgroundDark" | "component.notification.background" | "component.notification.backgroundDark" | "component.notification.border" | "component.notification.borderDark" | "component.notification.foreground" | "component.notification.foregroundDark" | "component.notification.icon" | "component.notification.iconDark" | "component.notification.successBackground" | "component.notification.successBackgroundDark" | "component.notification.successBorder" | "component.notification.successBorderDark" | "component.notification.successForeground" | "component.notification.successForegroundDark" | "component.notification.dangerBorder" | "component.notification.dangerBorderDark" | "component.notification.dangerForeground" | "component.notification.dangerForegroundDark" | "component.notification.badgeBackground" | "component.notification.badgeForeground" | "component.menu.background" | "component.menu.backgroundDark" | "component.menu.border" | "component.menu.borderDark" | "component.menu.radius" | "component.menu.shadow" | "component.menu.shadowDark" | "component.menu.itemBackgroundHover" | "component.menu.itemBackgroundHoverDark" | "component.menu.itemText" | "component.menu.itemTextDark" | "component.menu.itemIcon" | "component.menu.itemIconDark" | "component.menu.itemShortcut" | "component.menu.itemShortcutDark" | "component.menu.itemDangerText" | "component.menu.itemDangerTextDark" | "component.menu.itemDangerBackgroundHover" | "component.menu.itemDangerBackgroundHoverDark" | "component.menu.itemHeight" | "component.menu.separator" | "component.menu.separatorDark" | "component.menu.label" | "component.menu.labelDark" | "component.palette.background" | "component.palette.backgroundDark" | "component.palette.border" | "component.palette.borderDark" | "component.palette.shadow" | "component.palette.shadowDark" | "component.palette.scrim" | "component.palette.scrimDark" | "component.palette.width" | "component.palette.inputHeight" | "component.palette.itemHeight" | "component.palette.itemBackgroundActive" | "component.palette.itemBackgroundActiveDark" | "component.palette.groupLabel" | "component.palette.groupLabelDark" | "component.palette.itemMeta" | "component.palette.itemMetaDark" | "component.sheet.background" | "component.sheet.backgroundDark" | "component.sheet.border" | "component.sheet.borderDark" | "component.sheet.shadow" | "component.sheet.shadowDark" | "component.sheet.scrim" | "component.sheet.scrimDark" | "component.sheet.width" | "component.avatar.yellow" | "component.avatar.green" | "component.avatar.red" | "component.avatar.blue" | "component.avatar.purple" | "component.avatar.teal" | "component.avatar.orange" | "component.avatar.foreground" | "component.avatar.foregroundWarm" | "component.alert.radius" | "component.alert.infoBackground" | "component.alert.infoBackgroundDark" | "component.alert.infoBorder" | "component.alert.infoBorderDark" | "component.alert.infoText" | "component.alert.infoTextDark" | "component.alert.infoBody" | "component.alert.infoBodyDark" | "component.alert.infoIcon" | "component.alert.infoIconDark" | "component.alert.brandBackground" | "component.alert.brandBackgroundDark" | "component.alert.brandBorder" | "component.alert.brandBorderDark" | "component.alert.brandText" | "component.alert.brandTextDark" | "component.alert.brandBody" | "component.alert.brandBodyDark" | "component.alert.brandIcon" | "component.alert.brandIconDark" | "component.alert.successBackground" | "component.alert.successBackgroundDark" | "component.alert.successBorder" | "component.alert.successBorderDark" | "component.alert.successText" | "component.alert.successTextDark" | "component.alert.successBody" | "component.alert.successBodyDark" | "component.alert.successIcon" | "component.alert.successIconDark" | "component.alert.dangerBackground" | "component.alert.dangerBackgroundDark" | "component.alert.dangerBorder" | "component.alert.dangerBorderDark" | "component.alert.dangerText" | "component.alert.dangerTextDark" | "component.alert.dangerBody" | "component.alert.dangerBodyDark" | "component.alert.dangerIcon" | "component.alert.dangerIconDark" | "component.slider.track" | "component.slider.trackDark" | "component.slider.buffer" | "component.slider.bufferDark" | "component.slider.fill" | "component.slider.knob" | "component.slider.fillDisabled" | "component.slider.fillDisabledDark" | "component.slider.trackHeight" | "component.slider.knobSize" | "component.slider.hitHeight" | "component.pagination.itemSize" | "component.pagination.itemText" | "component.pagination.itemTextDark" | "component.pagination.itemTextActive" | "component.pagination.itemTextActiveDark" | "component.pagination.itemBackgroundHover" | "component.pagination.itemBackgroundHoverDark" | "component.pagination.itemBackgroundActive" | "component.pagination.itemBackgroundActiveDark" | "component.pagination.itemBorderActive" | "component.pagination.itemBorderActiveDark" | "context.tv.text.primary" | "context.tv.text.secondary" | "context.tv.text.tertiary" | "context.tv.channelArt.production.posterBackground" | "context.tv.channelArt.production.splashBackground" | "context.tv.channelArt.development.background" | "context.tv.channelArt.development.accent" | "context.tv.channelArt.development.grid" | "context.tv.channelArt.nightly.background" | "context.tv.channelArt.nightly.accent" | "context.tv.channelArt.nightly.star" | "context.tv.channelArt.nightly.moon" | "context.tv.channelArt.nightly.moonCrater" | "context.tv.channelArt.lab.background" | "context.tv.channelArt.lab.foreground" | "context.tv.channelArt.lab.accent" | "tv.video.background" | "tv.video.heroScrimTop" | "tv.video.heroScrimBottom" | "tv.video.textOnVideo" | "tv.text.heading" | "tv.text.label" | "tv.text.body" | "tv.text.caption" | "tv.text.smol" | "tv.fontWeight.regular" | "tv.fontWeight.medium" | "tv.space.xxs" | "tv.space.xs" | "tv.space.sm" | "tv.space.md" | "tv.space.lg" | "tv.space.xl" | "tv.space.xxl" | "tv.overscan.x" | "tv.overscan.y" | "tv.radius" | "tv.focus.borderWidth" | "tv.focus.row.background" | "tv.focus.row.backgroundFocused" | "tv.focus.control.background" | "tv.focus.control.backgroundFocused" | "tv.focus.control.border" | "tv.focus.control.borderFocused" | "tv.z.modal" | "tv.z.toast" | "tv.z.overlay" | "color.brand.yellow" | "color.neutral.light.bg" | "color.neutral.light.bgSecondary" | "color.neutral.light.componentBg" | "color.neutral.light.componentBgHover" | "color.neutral.light.componentBgActive" | "color.neutral.light.line" | "color.neutral.light.border" | "color.neutral.light.borderHover" | "color.neutral.light.solid" | "color.neutral.light.solidHover" | "color.neutral.light.textSecondary" | "color.neutral.light.text" | "color.neutral.dark.bg" | "color.neutral.dark.bgSecondary" | "color.neutral.dark.componentBg" | "color.neutral.dark.componentBgHover" | "color.neutral.dark.componentBgActive" | "color.neutral.dark.line" | "color.neutral.dark.border" | "color.neutral.dark.borderHover" | "color.neutral.dark.solid" | "color.neutral.dark.solidHover" | "color.neutral.dark.textSecondary" | "color.neutral.dark.text" | "color.green.light.bg" | "color.green.light.bgSecondary" | "color.green.light.componentBg" | "color.green.light.componentBgHover" | "color.green.light.componentBgActive" | "color.green.light.line" | "color.green.light.border" | "color.green.light.borderHover" | "color.green.light.solid" | "color.green.light.solidHover" | "color.green.light.textSecondary" | "color.green.light.text" | "color.green.dark.bg" | "color.green.dark.bgSecondary" | "color.green.dark.componentBg" | "color.green.dark.componentBgHover" | "color.green.dark.componentBgActive" | "color.green.dark.line" | "color.green.dark.border" | "color.green.dark.borderHover" | "color.green.dark.solid" | "color.green.dark.solidHover" | "color.green.dark.textSecondary" | "color.green.dark.text" | "color.red.light.bg" | "color.red.light.bgSecondary" | "color.red.light.componentBg" | "color.red.light.componentBgHover" | "color.red.light.componentBgActive" | "color.red.light.line" | "color.red.light.border" | "color.red.light.borderHover" | "color.red.light.solid" | "color.red.light.solidHover" | "color.red.light.textSecondary" | "color.red.light.text" | "color.red.dark.bg" | "color.red.dark.bgSecondary" | "color.red.dark.componentBg" | "color.red.dark.componentBgHover" | "color.red.dark.componentBgActive" | "color.red.dark.line" | "color.red.dark.border" | "color.red.dark.borderHover" | "color.red.dark.solid" | "color.red.dark.solidHover" | "color.red.dark.textSecondary" | "color.red.dark.text" | "color.yellow.light.bg" | "color.yellow.light.bgSecondary" | "color.yellow.light.componentBg" | "color.yellow.light.componentBgHover" | "color.yellow.light.componentBgActive" | "color.yellow.light.line" | "color.yellow.light.border" | "color.yellow.light.borderHover" | "color.yellow.light.solidHover" | "color.yellow.light.textSecondary" | "color.yellow.light.text" | "color.yellow.dark.bg" | "color.yellow.dark.bgSecondary" | "color.yellow.dark.componentBg" | "color.yellow.dark.componentBgHover" | "color.yellow.dark.componentBgActive" | "color.yellow.dark.line" | "color.yellow.dark.border" | "color.yellow.dark.borderHover" | "color.yellow.dark.solidHover" | "color.yellow.dark.textSecondary" | "color.yellow.dark.text" | "color.transfer.light.lime3" | "color.transfer.dark.lime3" | "elevation.shadowColor" | "elevation.color" | "elevation.sm" | "elevation.md" | "elevation.lg" | "elevation.focusColor" | "elevation.focus" | "elevation.focusDark" | "typography.fontFamily.sans" | "typography.fontFamily.display" | "typography.fontFamily.mono" | "typography.fontSize.xs" | "typography.fontSize.sm" | "typography.fontSize.base" | "typography.fontSize.md" | "typography.fontSize.lg" | "typography.fontSize.xl" | "typography.fontSize.2xl" | "typography.fontSize.3xl" | "typography.fontSize.4xl" | "typography.fontSize.display" | "typography.lineHeight.tight" | "typography.lineHeight.snug" | "typography.lineHeight.normal" | "typography.lineHeight.loose" | "typography.fontWeight.regular" | "typography.fontWeight.medium" | "typography.fontWeight.bold" | "typography.fontWeight.black" | "typography.letterSpacing.tight" | "typography.letterSpacing.normal" | "typography.letterSpacing.wide" | "typography.letterSpacing.uppercase" | "spacing.0" | "spacing.1" | "spacing.2" | "spacing.3" | "spacing.4" | "spacing.5" | "spacing.6" | "spacing.7" | "spacing.8" | "radius.sm" | "radius.default" | "radius.md" | "radius.lg" | "radius.pill" | "radius.tv" | "border.width" | "motion.easing.out" | "motion.easing.inOut" | "motion.duration.fast" | "motion.duration.reveal" | "motion.duration.base" | "motion.duration.slow" | "z.dropdown" | "z.sticky" | "z.modal" | "z.notification" | "z.tooltip" | "breakpoint.sm" | "breakpoint.md" | "breakpoint.lg" | "surface.light.htmlBg" | "surface.light.appBg" | "surface.light.navBg" | "surface.light.navItemBg" | "surface.light.navItemBgHover" | "surface.light.navItemBgActive" | "surface.light.listItemBg" | "surface.light.listItemBgHover" | "surface.light.listItemBgActive" | "surface.light.listItemBorder" | "surface.light.segmentedControlBg" | "surface.light.segmentedControlBgActive" | "surface.light.transferListItemCompletingBg" | "surface.light.transferListItemDownloadingBg" | "surface.light.transferListItemFinishedBg" | "surface.light.transferListItemPassiveBg" | "surface.light.hiContrast" | "surface.light.loContrast" | "surface.light.transparent" | "surface.light.overlayInline" | "surface.light.overlayFull" | "surface.dark.htmlBg" | "surface.dark.appBg" | "surface.dark.navBg" | "surface.dark.navItemBg" | "surface.dark.navItemBgHover" | "surface.dark.navItemBgActive" | "surface.dark.listItemBg" | "surface.dark.listItemBgHover" | "surface.dark.listItemBgActive" | "surface.dark.listItemBorder" | "surface.dark.segmentedControlBg" | "surface.dark.segmentedControlBgActive" | "surface.dark.transferListItemCompletingBg" | "surface.dark.transferListItemDownloadingBg" | "surface.dark.transferListItemFinishedBg" | "surface.dark.transferListItemPassiveBg" | "surface.dark.hiContrast" | "surface.dark.loContrast" | "surface.dark.overlayInline" | "surface.dark.overlayFull" | "surface.dark.shadowColor" | "surface.dark.shadow" | "surface.dark.shadowSm" | "surface.dark.shadowMd" | "surface.dark.shadowLg";
|
|
4
4
|
|
|
5
5
|
export type PutioToken = {
|
|
6
6
|
readonly cssName: string;
|
package/dist/tokens.dtcg.json
CHANGED
|
@@ -4746,11 +4746,24 @@
|
|
|
4746
4746
|
},
|
|
4747
4747
|
"focus": {
|
|
4748
4748
|
"$type": "string",
|
|
4749
|
-
"$value": "0 0 0
|
|
4749
|
+
"$value": "0 0 0 2px {color.neutral.light.bg}, 0 0 0 4px {color.neutral.light.solidHover}",
|
|
4750
4750
|
"$extensions": {
|
|
4751
4751
|
"putio": {
|
|
4752
4752
|
"cssName": "shadow-focus",
|
|
4753
|
-
"mode": "
|
|
4753
|
+
"mode": "light",
|
|
4754
|
+
"figma": false
|
|
4755
|
+
}
|
|
4756
|
+
},
|
|
4757
|
+
"$description": "Button, link, and nav focus: a 2px page-coloured gap, then a 2px opaque ring at least 3:1 against the page and panels."
|
|
4758
|
+
},
|
|
4759
|
+
"focusDark": {
|
|
4760
|
+
"$type": "string",
|
|
4761
|
+
"$value": "0 0 0 2px {color.neutral.dark.bg}, 0 0 0 4px {color.neutral.dark.solidHover}",
|
|
4762
|
+
"$description": "Dark-mode button, link, and nav focus ring.",
|
|
4763
|
+
"$extensions": {
|
|
4764
|
+
"putio": {
|
|
4765
|
+
"cssName": "shadow-focus",
|
|
4766
|
+
"mode": "dark",
|
|
4754
4767
|
"figma": false
|
|
4755
4768
|
}
|
|
4756
4769
|
}
|
|
@@ -5273,6 +5286,17 @@
|
|
|
5273
5286
|
}
|
|
5274
5287
|
}
|
|
5275
5288
|
},
|
|
5289
|
+
"reveal": {
|
|
5290
|
+
"$type": "duration",
|
|
5291
|
+
"$value": "180ms",
|
|
5292
|
+
"$extensions": {
|
|
5293
|
+
"putio": {
|
|
5294
|
+
"cssName": "dur-reveal",
|
|
5295
|
+
"mode": "global",
|
|
5296
|
+
"figma": true
|
|
5297
|
+
}
|
|
5298
|
+
}
|
|
5299
|
+
},
|
|
5276
5300
|
"base": {
|
|
5277
5301
|
"$type": "duration",
|
|
5278
5302
|
"$value": "200ms",
|
package/dist/tokens.flat.json
CHANGED
|
@@ -3234,9 +3234,18 @@
|
|
|
3234
3234
|
"elevation.focus": {
|
|
3235
3235
|
"cssName": "--shadow-focus",
|
|
3236
3236
|
"type": "string",
|
|
3237
|
-
"mode": "
|
|
3238
|
-
"value": "0 0 0
|
|
3239
|
-
"originalValue": "0 0 0
|
|
3237
|
+
"mode": "light",
|
|
3238
|
+
"value": "0 0 0 2px hsl(0, 0%, 99.0%), 0 0 0 4px hsl(0, 0%, 52.3%)",
|
|
3239
|
+
"originalValue": "0 0 0 2px {color.neutral.light.bg}, 0 0 0 4px {color.neutral.light.solidHover}",
|
|
3240
|
+
"description": "Button, link, and nav focus: a 2px page-coloured gap, then a 2px opaque ring at least 3:1 against the page and panels."
|
|
3241
|
+
},
|
|
3242
|
+
"elevation.focusDark": {
|
|
3243
|
+
"cssName": "--shadow-focus",
|
|
3244
|
+
"type": "string",
|
|
3245
|
+
"mode": "dark",
|
|
3246
|
+
"value": "0 0 0 2px hsl(0, 0%, 8.5%), 0 0 0 4px hsl(0, 0%, 49.4%)",
|
|
3247
|
+
"originalValue": "0 0 0 2px {color.neutral.dark.bg}, 0 0 0 4px {color.neutral.dark.solidHover}",
|
|
3248
|
+
"description": "Dark-mode button, link, and nav focus ring."
|
|
3240
3249
|
},
|
|
3241
3250
|
"typography.fontFamily.sans": {
|
|
3242
3251
|
"cssName": "--font-sans",
|
|
@@ -3557,6 +3566,13 @@
|
|
|
3557
3566
|
"value": "120ms",
|
|
3558
3567
|
"originalValue": "120ms"
|
|
3559
3568
|
},
|
|
3569
|
+
"motion.duration.reveal": {
|
|
3570
|
+
"cssName": "--dur-reveal",
|
|
3571
|
+
"type": "duration",
|
|
3572
|
+
"mode": "global",
|
|
3573
|
+
"value": "180ms",
|
|
3574
|
+
"originalValue": "180ms"
|
|
3575
|
+
},
|
|
3560
3576
|
"motion.duration.base": {
|
|
3561
3577
|
"cssName": "--dur-base",
|
|
3562
3578
|
"type": "duration",
|
package/dist/tokens.js
CHANGED
|
@@ -3236,9 +3236,18 @@ export const tokens = {
|
|
|
3236
3236
|
"elevation.focus": {
|
|
3237
3237
|
"cssName": "--shadow-focus",
|
|
3238
3238
|
"type": "string",
|
|
3239
|
-
"mode": "
|
|
3240
|
-
"value": "0 0 0
|
|
3241
|
-
"originalValue": "0 0 0
|
|
3239
|
+
"mode": "light",
|
|
3240
|
+
"value": "0 0 0 2px hsl(0, 0%, 99.0%), 0 0 0 4px hsl(0, 0%, 52.3%)",
|
|
3241
|
+
"originalValue": "0 0 0 2px {color.neutral.light.bg}, 0 0 0 4px {color.neutral.light.solidHover}",
|
|
3242
|
+
"description": "Button, link, and nav focus: a 2px page-coloured gap, then a 2px opaque ring at least 3:1 against the page and panels."
|
|
3243
|
+
},
|
|
3244
|
+
"elevation.focusDark": {
|
|
3245
|
+
"cssName": "--shadow-focus",
|
|
3246
|
+
"type": "string",
|
|
3247
|
+
"mode": "dark",
|
|
3248
|
+
"value": "0 0 0 2px hsl(0, 0%, 8.5%), 0 0 0 4px hsl(0, 0%, 49.4%)",
|
|
3249
|
+
"originalValue": "0 0 0 2px {color.neutral.dark.bg}, 0 0 0 4px {color.neutral.dark.solidHover}",
|
|
3250
|
+
"description": "Dark-mode button, link, and nav focus ring."
|
|
3242
3251
|
},
|
|
3243
3252
|
"typography.fontFamily.sans": {
|
|
3244
3253
|
"cssName": "--font-sans",
|
|
@@ -3559,6 +3568,13 @@ export const tokens = {
|
|
|
3559
3568
|
"value": "120ms",
|
|
3560
3569
|
"originalValue": "120ms"
|
|
3561
3570
|
},
|
|
3571
|
+
"motion.duration.reveal": {
|
|
3572
|
+
"cssName": "--dur-reveal",
|
|
3573
|
+
"type": "duration",
|
|
3574
|
+
"mode": "global",
|
|
3575
|
+
"value": "180ms",
|
|
3576
|
+
"originalValue": "180ms"
|
|
3577
|
+
},
|
|
3562
3578
|
"motion.duration.base": {
|
|
3563
3579
|
"cssName": "--dur-base",
|
|
3564
3580
|
"type": "duration",
|
package/package.json
CHANGED
package/system/README.md
CHANGED
|
@@ -83,7 +83,7 @@ its cards use itself.
|
|
|
83
83
|
|
|
84
84
|
## Core rules
|
|
85
85
|
|
|
86
|
-
- **Yellow** follows [Colors](../DESIGN.md#colors). Guide specifics: `--yellow-solid-hover` is the hover peer with one value in both modes, and button focus-visible rings use `--shadow-focus`
|
|
86
|
+
- **Yellow** follows [Colors](../DESIGN.md#colors). Guide specifics: `--yellow-solid-hover` is the hover peer with one value in both modes, and button focus-visible rings use `--shadow-focus`: a 2px `--bg` gap, then a 2px `--solid-hover` ring, at least 3:1 against the page and panels. `--shadow-focus-color` (the yellow at 35% alpha) stays only as shadcn's `--ring`. Form fields focus with `--field-ring` instead.
|
|
87
87
|
- **Yellow as text on light** uses `--yellow-text-secondary` (≈5:1, AA); `--yellow-solid` is fill-only on light backgrounds.
|
|
88
88
|
- **Labels on yellow** use `--primary-foreground`, a warm dark that passes AA on the yellow fill.
|
|
89
89
|
- **One design, two modes.** Light and dark are the same markup and components with different token values. Toggle `.dark` on `<html>`; one page serves both modes. Components consume semantic tokens (`--bg`, `--text`, `--border`, `--accent`, …) instead of raw `#hex` or `hsl()`.
|
|
@@ -172,10 +172,8 @@ directly.
|
|
|
172
172
|
|
|
173
173
|
shadcn marks parts of compound components with `data-slot="card-header"`,
|
|
174
174
|
`data-slot="card-title"`, and so on. put.io does the same on the folder picker
|
|
175
|
-
(`data-slot="modal" / "modal-header" / "modal-body" / "modal-footer"`)
|
|
176
|
-
|
|
177
|
-
(`data-slot="auth" / "auth-header" / "auth-body"`), so external CSS can target
|
|
178
|
-
one part without nested class chains.
|
|
175
|
+
(`data-slot="modal" / "modal-header" / "modal-body" / "modal-footer"`), so
|
|
176
|
+
external CSS can target one part without nested class chains.
|
|
179
177
|
|
|
180
178
|
## Design variants
|
|
181
179
|
|
package/system/components.css
CHANGED
|
@@ -147,11 +147,24 @@ button i { font-size: var(--button-icon-size); line-height: 1; display: inline-f
|
|
|
147
147
|
.btn-ghost:disabled { opacity: 1; color: var(--solid); background: transparent; }
|
|
148
148
|
|
|
149
149
|
/* States */
|
|
150
|
-
/*
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
150
|
+
/* Bare disabled buttons fade; hover styles above are gated on :not(:disabled).
|
|
151
|
+
Filled variants instead drop their fill to --solid at full opacity, so a
|
|
152
|
+
disabled "Verifying…" stays legible. A finished action keeps its success
|
|
153
|
+
fill with data-state="success" (2FA "Verified"). */
|
|
154
154
|
button:disabled { opacity: 0.3; cursor: not-allowed; }
|
|
155
|
+
:is(.btn-primary, .btn-success, .btn-danger, .btn-info, .btn-invert):not(.btn-quiet):disabled {
|
|
156
|
+
opacity: 1;
|
|
157
|
+
background: var(--solid);
|
|
158
|
+
border-color: var(--solid);
|
|
159
|
+
color: var(--solid-foreground);
|
|
160
|
+
}
|
|
161
|
+
.btn-default:not(.btn-quiet):disabled { opacity: 1; color: var(--solid); }
|
|
162
|
+
.btn-success[data-state="success"]:disabled {
|
|
163
|
+
background: var(--button-success-bg);
|
|
164
|
+
border-color: var(--button-success-bg);
|
|
165
|
+
color: var(--button-success-fg);
|
|
166
|
+
}
|
|
167
|
+
/* An opaque double ring: a --bg gap, then --solid-hover, ≥3:1 on page and panels. */
|
|
155
168
|
button:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
|
|
156
169
|
|
|
157
170
|
/* Loading state — hides label, paints a CSS spinner over the button */
|
|
@@ -211,8 +224,9 @@ input, textarea, select { text-transform: none; letter-spacing: normal; }
|
|
|
211
224
|
|
|
212
225
|
.card = focal, elevated component surface. Sits ON --bg,
|
|
213
226
|
uses --component-bg so it reads as raised in dark
|
|
214
|
-
and contained in light.
|
|
215
|
-
|
|
227
|
+
and contained in light. Modal, settings card,
|
|
228
|
+
anything the user's attention should go TO. Auth
|
|
229
|
+
pages take neither: see .auth-page.
|
|
216
230
|
|
|
217
231
|
.panel = quiet inline reference container. Sits ON --bg,
|
|
218
232
|
uses --bg-secondary so it stays recessive but
|
|
@@ -298,17 +312,20 @@ input, textarea, select { text-transform: none; letter-spacing: normal; }
|
|
|
298
312
|
}
|
|
299
313
|
/* Invalid — border + text only, no surface fill.
|
|
300
314
|
Step convention: rest = step 7 (--red-border),
|
|
301
|
-
|
|
315
|
+
hover = step 8 (--red-border-hover), focus = step 9 (--red-solid),
|
|
316
|
+
which holds 3:1 against the field fill.
|
|
317
|
+
The border fades in over --dur-reveal, in step with .form-reveal. */
|
|
302
318
|
.field[aria-invalid="true"] {
|
|
303
319
|
border-color: var(--red-border);
|
|
320
|
+
transition-duration: var(--dur-reveal);
|
|
304
321
|
}
|
|
305
322
|
.field[aria-invalid="true"]:hover {
|
|
306
323
|
border-color: var(--red-border-hover);
|
|
307
324
|
}
|
|
308
325
|
.field[aria-invalid="true"]:focus,
|
|
309
326
|
.field[aria-invalid="true"]:focus-visible {
|
|
310
|
-
border-color: var(--red-
|
|
311
|
-
box-shadow: 0 0 0 1px var(--red-
|
|
327
|
+
border-color: var(--red-solid);
|
|
328
|
+
box-shadow: 0 0 0 1px var(--red-solid);
|
|
312
329
|
}
|
|
313
330
|
/* Loading / async-validating — suppress focus ring so the spinner
|
|
314
331
|
reads as the dominant signal. */
|
|
@@ -407,6 +424,38 @@ input, textarea, select { text-transform: none; letter-spacing: normal; }
|
|
|
407
424
|
font-size: var(--fs-sm);
|
|
408
425
|
}
|
|
409
426
|
|
|
427
|
+
/* ===========================================================
|
|
428
|
+
Form reveal — eases a field or form error in without a layout jump.
|
|
429
|
+
|
|
430
|
+
Every field error uses it: under its field inside .form-group, or
|
|
431
|
+
as a form's one message above the submit button. The row animates
|
|
432
|
+
its height through grid-template-rows (0fr → 1fr) with opacity, so
|
|
433
|
+
whatever sits below slides instead of jumping. Markup:
|
|
434
|
+
.form-reveal > div > .form-callout.inline[data-state="error"]; the
|
|
435
|
+
inner div clips, so spacing on the message collapses with it. Keep
|
|
436
|
+
the message (role="alert") mounted and rendered, so screen readers
|
|
437
|
+
hear new text: set its text and data-state="open" together; on
|
|
438
|
+
close, set data-state="closed" and empty the message once the row
|
|
439
|
+
has collapsed (transitionend), so it does not snap and a closed row
|
|
440
|
+
says nothing. The token base collapses the transition under
|
|
441
|
+
prefers-reduced-motion.
|
|
442
|
+
=========================================================== */
|
|
443
|
+
.form-reveal {
|
|
444
|
+
display: grid;
|
|
445
|
+
grid-template-rows: 0fr;
|
|
446
|
+
opacity: 0;
|
|
447
|
+
transition:
|
|
448
|
+
grid-template-rows var(--dur-reveal) var(--ease-out),
|
|
449
|
+
opacity var(--dur-reveal) var(--ease-out);
|
|
450
|
+
}
|
|
451
|
+
.form-reveal > * { min-height: 0; overflow: hidden; }
|
|
452
|
+
.form-reveal .form-callout { margin: 0; }
|
|
453
|
+
.form-reveal[data-state="open"] { grid-template-rows: 1fr; opacity: 1; }
|
|
454
|
+
/* Inside a .form-group the row absorbs the group gap, so a closed row
|
|
455
|
+
adds no space and an open one sits the usual 6px under its field. */
|
|
456
|
+
.form-group > .form-reveal { margin-top: -6px; }
|
|
457
|
+
.form-group > .form-reveal .form-callout { padding-top: 6px; }
|
|
458
|
+
|
|
410
459
|
/* ===========================================================
|
|
411
460
|
One-time password — one real input, six visual slots.
|
|
412
461
|
|
|
@@ -483,10 +532,11 @@ input, textarea, select { text-transform: none; letter-spacing: normal; }
|
|
|
483
532
|
.otp:has(.otp-input[aria-invalid="true"]) .otp-slot {
|
|
484
533
|
border-color: var(--red-border);
|
|
485
534
|
color: var(--red-text-secondary);
|
|
535
|
+
transition-duration: var(--dur-reveal);
|
|
486
536
|
}
|
|
487
537
|
.otp:has(.otp-input[aria-invalid="true"]):focus-within .otp-slot[data-state="active"] {
|
|
488
|
-
border-color: var(--red-
|
|
489
|
-
box-shadow: 0 0 0 1px var(--red-
|
|
538
|
+
border-color: var(--red-solid);
|
|
539
|
+
box-shadow: 0 0 0 1px var(--red-solid);
|
|
490
540
|
}
|
|
491
541
|
.otp[data-state="success"] .otp-slot {
|
|
492
542
|
border-color: var(--green-border);
|
|
@@ -512,6 +562,100 @@ input, textarea, select { text-transform: none; letter-spacing: normal; }
|
|
|
512
562
|
cursor: not-allowed;
|
|
513
563
|
}
|
|
514
564
|
|
|
565
|
+
/* ===========================================================
|
|
566
|
+
Auth page — sign in, sign up, password reset, two-factor.
|
|
567
|
+
|
|
568
|
+
Card-less: the form sits on the page background. Logo top-left
|
|
569
|
+
in .auth-header, one left-aligned 340px column centred in
|
|
570
|
+
.auth-main, a quiet link row in .auth-footer. The page re-points
|
|
571
|
+
--field-bg / --field-border, so .field and .otp-slot render filled
|
|
572
|
+
without a variant. Controls are 44px; the title is the only
|
|
573
|
+
heading. Under 640px the gutters drop to 24px so the logo lines
|
|
574
|
+
up with the column.
|
|
575
|
+
=========================================================== */
|
|
576
|
+
.auth-page {
|
|
577
|
+
--field-bg: var(--bg-secondary);
|
|
578
|
+
--field-border: var(--line);
|
|
579
|
+
/* Focus a step past hover, so it holds 3:1 against the filled field. */
|
|
580
|
+
--field-border-focus: var(--solid-hover);
|
|
581
|
+
--field-ring: 0 0 0 1px var(--solid-hover);
|
|
582
|
+
box-sizing: border-box;
|
|
583
|
+
min-height: 100dvh;
|
|
584
|
+
display: flex;
|
|
585
|
+
flex-direction: column;
|
|
586
|
+
background: var(--bg);
|
|
587
|
+
color: var(--text);
|
|
588
|
+
}
|
|
589
|
+
.auth-header {
|
|
590
|
+
display: flex;
|
|
591
|
+
align-items: center;
|
|
592
|
+
justify-content: space-between;
|
|
593
|
+
gap: 16px;
|
|
594
|
+
padding: 28px 32px;
|
|
595
|
+
}
|
|
596
|
+
.auth-logo { display: block; height: 30.33px; width: auto; }
|
|
597
|
+
.auth-main {
|
|
598
|
+
flex: 1 0 auto;
|
|
599
|
+
display: flex;
|
|
600
|
+
align-items: center;
|
|
601
|
+
justify-content: center;
|
|
602
|
+
padding: 24px 24px 48px;
|
|
603
|
+
}
|
|
604
|
+
.auth-column {
|
|
605
|
+
width: 100%;
|
|
606
|
+
max-width: 340px;
|
|
607
|
+
display: flex;
|
|
608
|
+
flex-direction: column;
|
|
609
|
+
}
|
|
610
|
+
.auth-title {
|
|
611
|
+
margin: 0 0 28px;
|
|
612
|
+
font-size: 22px;
|
|
613
|
+
line-height: 30px;
|
|
614
|
+
font-weight: var(--fw-medium);
|
|
615
|
+
letter-spacing: -0.01em;
|
|
616
|
+
color: var(--text);
|
|
617
|
+
}
|
|
618
|
+
.auth-column .form-stack { gap: 16px; }
|
|
619
|
+
.auth-column .label {
|
|
620
|
+
font-size: var(--fs-sm);
|
|
621
|
+
font-weight: var(--fw-regular);
|
|
622
|
+
color: var(--text-secondary);
|
|
623
|
+
}
|
|
624
|
+
.auth-column .field { height: 44px; }
|
|
625
|
+
.auth-column form > .form-reveal .form-callout { padding-top: 12px; font-size: var(--fs-base); }
|
|
626
|
+
.auth-column .btn-block { height: 44px; }
|
|
627
|
+
.auth-column form > .form-reveal + .btn-block { margin-top: 16px; }
|
|
628
|
+
.auth-links {
|
|
629
|
+
margin: 24px 0 0;
|
|
630
|
+
display: flex;
|
|
631
|
+
flex-wrap: wrap;
|
|
632
|
+
align-items: baseline;
|
|
633
|
+
justify-content: space-between;
|
|
634
|
+
gap: 8px 16px;
|
|
635
|
+
color: var(--text-secondary);
|
|
636
|
+
font-size: var(--fs-base);
|
|
637
|
+
}
|
|
638
|
+
/* A prompt's link reads as text ("New to put.io? Sign up"); a bare
|
|
639
|
+
action link ("Use a recovery code") stays muted. */
|
|
640
|
+
.auth-links p { margin: 0; }
|
|
641
|
+
.auth-links a { color: var(--text); text-underline-offset: 3px; }
|
|
642
|
+
.auth-links > a { color: var(--text-secondary); text-decoration: none; }
|
|
643
|
+
.auth-links > a:hover { color: var(--text); }
|
|
644
|
+
.auth-footer {
|
|
645
|
+
display: flex;
|
|
646
|
+
flex-wrap: wrap;
|
|
647
|
+
justify-content: center;
|
|
648
|
+
gap: 8px 16px;
|
|
649
|
+
padding: 24px 32px 28px;
|
|
650
|
+
font-size: var(--fs-sm);
|
|
651
|
+
}
|
|
652
|
+
.auth-footer a { color: var(--text-secondary); text-decoration: none; }
|
|
653
|
+
.auth-footer a:hover { color: var(--text); }
|
|
654
|
+
@media (max-width: 640px) {
|
|
655
|
+
.auth-header { padding: 24px; }
|
|
656
|
+
.auth-footer { padding: 24px; }
|
|
657
|
+
}
|
|
658
|
+
|
|
515
659
|
/* Floating-menu surface — one recipe for dropdowns, context menus,
|
|
516
660
|
submenus, and on-player popovers. Cards keep their item styles local.
|
|
517
661
|
Consumed by web-c09-menu.html and web-p06-player.html — it looks unused
|
|
@@ -86,11 +86,24 @@
|
|
|
86
86
|
},
|
|
87
87
|
"focus": {
|
|
88
88
|
"$type": "string",
|
|
89
|
-
"$value": "0 0 0
|
|
89
|
+
"$value": "0 0 0 2px {color.neutral.light.bg}, 0 0 0 4px {color.neutral.light.solidHover}",
|
|
90
90
|
"$extensions": {
|
|
91
91
|
"putio": {
|
|
92
92
|
"cssName": "shadow-focus",
|
|
93
|
-
"mode": "
|
|
93
|
+
"mode": "light",
|
|
94
|
+
"figma": false
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"$description": "Button, link, and nav focus: a 2px page-coloured gap, then a 2px opaque ring at least 3:1 against the page and panels."
|
|
98
|
+
},
|
|
99
|
+
"focusDark": {
|
|
100
|
+
"$type": "string",
|
|
101
|
+
"$value": "0 0 0 2px {color.neutral.dark.bg}, 0 0 0 4px {color.neutral.dark.solidHover}",
|
|
102
|
+
"$description": "Dark-mode button, link, and nav focus ring.",
|
|
103
|
+
"$extensions": {
|
|
104
|
+
"putio": {
|
|
105
|
+
"cssName": "shadow-focus",
|
|
106
|
+
"mode": "dark",
|
|
94
107
|
"figma": false
|
|
95
108
|
}
|
|
96
109
|
}
|
|
@@ -613,6 +626,17 @@
|
|
|
613
626
|
}
|
|
614
627
|
}
|
|
615
628
|
},
|
|
629
|
+
"reveal": {
|
|
630
|
+
"$type": "duration",
|
|
631
|
+
"$value": "180ms",
|
|
632
|
+
"$extensions": {
|
|
633
|
+
"putio": {
|
|
634
|
+
"cssName": "dur-reveal",
|
|
635
|
+
"mode": "global",
|
|
636
|
+
"figma": true
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
},
|
|
616
640
|
"base": {
|
|
617
641
|
"$type": "duration",
|
|
618
642
|
"$value": "200ms",
|