diff options
| author | Frank <[email protected]> | 2025-08-08 13:22:54 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-08-08 13:24:32 -0400 |
| commit | 183e0911b76025a1f2a82e979d9834fec2131d0e (patch) | |
| tree | 9987c1753bd64d1ce1d174ab397f1a8c681f642c /cloud/web/src/ui/style | |
| parent | c7bb19ad0712469063eab35589aa5d3602b0c5b1 (diff) | |
| download | opencode-183e0911b76025a1f2a82e979d9834fec2131d0e.tar.gz opencode-183e0911b76025a1f2a82e979d9834fec2131d0e.zip | |
wip: gateway
Diffstat (limited to 'cloud/web/src/ui/style')
| -rw-r--r-- | cloud/web/src/ui/style/component/button.css | 78 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/component/dialog.css | 84 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/component/input.css | 34 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/component/label.css | 17 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/component/title-bar.css | 32 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/index.css | 50 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/token/animation.css | 23 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/token/color.css | 88 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/token/font.css | 20 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/token/reset.css | 212 | ||||
| -rw-r--r-- | cloud/web/src/ui/style/token/space.css | 38 |
11 files changed, 676 insertions, 0 deletions
diff --git a/cloud/web/src/ui/style/component/button.css b/cloud/web/src/ui/style/component/button.css new file mode 100644 index 000000000..9604f9865 --- /dev/null +++ b/cloud/web/src/ui/style/component/button.css @@ -0,0 +1,78 @@ +[data-component="button"] { + width: fit-content; + display: flex; + line-height: 1; + align-items: center; + justify-content: center; + gap: var(--space-2); + font-size: var(--font-size-md); + text-transform: uppercase; + height: var(--space-11); + outline: none; + font-weight: 500; + padding: 0 var(--space-4); + border-width: 2px; + border-color: var(--color-border); + cursor: pointer; + + &:disabled { + opacity: 0.5; + cursor: default; + } + + &[data-color="primary"] { + background-color: var(--color-text); + border-color: var(--color-text); + color: var(--color-text-invert); + + &:active { + border-color: var(--color-accent); + } + } + + &[data-color="secondary"] { + &:active { + border-color: var(--color-accent); + } + } + + &[data-color="ghost"] { + border: none; + text-decoration: underline; + + &:active { + color: var(--color-text-accent); + } + } + + &:has([data-slot="icon"]) { + padding-left: var(--space-3); + padding-right: var(--space-3); + } + + &[data-size="sm"] { + height: var(--space-8); + padding: var(--space-3); + font-size: var(--font-size-xs); + + [data-slot="icon"] { + width: var(--space-3-5); + height: var(--space-3-5); + } + + &:has([data-slot="icon"]) { + padding-left: var(--space-2); + padding-right: var(--space-2); + } + } + + [data-slot="icon"] { + width: var(--space-4); + height: var(--space-4); + transition: transform 0.2s ease; + } + + &[data-rotate] [data-slot="icon"] { + transform: rotate(180deg); + } +} diff --git a/cloud/web/src/ui/style/component/dialog.css b/cloud/web/src/ui/style/component/dialog.css new file mode 100644 index 000000000..59867818f --- /dev/null +++ b/cloud/web/src/ui/style/component/dialog.css @@ -0,0 +1,84 @@ +[data-component="dialog-overlay"] { + pointer-events: none !important; + position: fixed; + inset: 0; + animation-name: fadeOut; + animation-duration: 200ms; + animation-timing-function: ease; + opacity: 0; + backdrop-filter: blur(2px); + + &[data-expanded] { + animation-name: fadeIn; + opacity: 1; + pointer-events: auto !important; + } +} + +[data-component="dialog-center"] { + position: fixed; + inset: 0; + padding-top: 10vh; + justify-content: center; + pointer-events: none; + + [data-slot="content"] { + width: 45rem; + margin: 0 auto; + transition: 150ms width; + background-color: var(--color-bg); + border-width: 2px; + border-color: var(--color-border); + overflow: hidden; + display: flex; + flex-direction: column; + gap: var(--space-3); + outline: none; + animation-duration: 1ms; + animation-name: zoomOut; + animation-timing-function: ease; + + box-shadow: 8px 8px 0px 0px var(--color-gray-4); + + &[data-expanded] { + animation-name: zoomIn; + } + + &[data-transition] { + animation-duration: 200ms; + } + + &[data-size="sm"] { + width: 30rem; + } + + [data-slot="header"] { + display: flex; + padding: var(--space-4) var(--space-4) 0; + + [data-slot="title"] { + } + } + + [data-slot="main"] { + padding: 0 var(--space-4); + + &:has([data-slot="options"]) { + padding: 0; + display: flex; + flex-direction: column; + gap: var(--space-4); + } + } + + [data-slot="input"] { + } + + [data-slot="footer"] { + padding: var(--space-4); + display: flex; + gap: var(--space-4); + justify-content: end; + } + } +} diff --git a/cloud/web/src/ui/style/component/input.css b/cloud/web/src/ui/style/component/input.css new file mode 100644 index 000000000..59535d763 --- /dev/null +++ b/cloud/web/src/ui/style/component/input.css @@ -0,0 +1,34 @@ +[data-component="input"] { + font-size: var(--font-size-md); + background: transparent; + caret-color: var(--color-accent); + font-family: var(--font-mono); + height: var(--space-11); + padding: 0 var(--space-4); + width: 100%; + resize: none; + border: 2px solid var(--color-border); + + &::placeholder { + color: var(--color-text-dimmed); + opacity: 0.75; + } + + &:focus { + outline: 0; + } + + &[data-size="sm"] { + height: var(--space-9); + padding: 0 var(--space-3); + font-size: var(--font-size-xs); + } + + &[data-size="md"] { + } + + &[data-size="lg"] { + height: var(--space-12); + font-size: var(--font-size-lg); + } +} diff --git a/cloud/web/src/ui/style/component/label.css b/cloud/web/src/ui/style/component/label.css new file mode 100644 index 000000000..e0dd5fef4 --- /dev/null +++ b/cloud/web/src/ui/style/component/label.css @@ -0,0 +1,17 @@ +[data-component="label"] { + letter-spacing: -0.03125rem; + text-transform: uppercase; + color: var(--color-text-dimmed); + font-weight: 500; + font-size: var(--font-size-md); + + &[data-size="sm"] { + font-size: var(--font-size-sm); + } + &[data-size="md"] { + } + &[data-size="lg"] { + font-size: var(--font-size-lg); + } +} + diff --git a/cloud/web/src/ui/style/component/title-bar.css b/cloud/web/src/ui/style/component/title-bar.css new file mode 100644 index 000000000..7ee32bfdc --- /dev/null +++ b/cloud/web/src/ui/style/component/title-bar.css @@ -0,0 +1,32 @@ +[data-component="title-bar"] { + display: flex; + align-items: center; + justify-content: space-between; + height: 72px; + padding: 0 var(--space-4); + border-bottom: 2px solid var(--color-border); + + [data-slot="left"] { + display: flex; + flex-direction: column; + gap: var(--space-1-5); + + h1 { + letter-spacing: -0.03125rem; + font-size: var(--font-size-xl); + text-transform: uppercase; + font-weight: 600; + } + + p { + color: var(--color-text-dimmed); + } + } + +} + +@media (max-width: 40rem) { + [data-component="title-bar"] { + display: none; + } +} diff --git a/cloud/web/src/ui/style/index.css b/cloud/web/src/ui/style/index.css new file mode 100644 index 000000000..117f596d0 --- /dev/null +++ b/cloud/web/src/ui/style/index.css @@ -0,0 +1,50 @@ +/* tokens */ +@import "./token/color.css"; +@import "./token/reset.css"; +@import "./token/animation.css"; +@import "./token/font.css"; +@import "./token/space.css"; + +/* components */ +@import "./component/label.css"; +@import "./component/input.css"; +@import "./component/button.css"; +@import "./component/dialog.css"; +@import "./component/title-bar.css"; + +body { + font-family: var(--font-mono); + line-height: 1; + color: var(--color-text); + background-color: var(--color-bg); + cursor: default; + user-select: none; + text-underline-offset: 0.1875rem; +} + +a { + text-decoration: underline; + &:active { + color: var(--color-text-accent); + } +} + +::selection { + background-color: var(--color-text-accent-invert); +} + +/* Responsive utilities */ +[data-max-width] { + width: 100%; + + & > * { + max-width: 90rem; + margin-left: auto; + margin-right: auto; + width: 100%; + } + + &[data-max-width-64] > * { + max-width: 64rem; + } +} diff --git a/cloud/web/src/ui/style/token/animation.css b/cloud/web/src/ui/style/token/animation.css new file mode 100644 index 000000000..a8edfeff5 --- /dev/null +++ b/cloud/web/src/ui/style/token/animation.css @@ -0,0 +1,23 @@ +@keyframes zoomIn { + from { + opacity: 0; + transform: scale(0.95); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +@keyframes zoomOut { + from { + opacity: 1; + transform: scale(1); + } + + to { + opacity: 0; + transform: scale(0.95); + } +} diff --git a/cloud/web/src/ui/style/token/color.css b/cloud/web/src/ui/style/token/color.css new file mode 100644 index 000000000..af0c46f3b --- /dev/null +++ b/cloud/web/src/ui/style/token/color.css @@ -0,0 +1,88 @@ +:root { + --color-white: hsl(0, 0%, 100%); + --color-gray-1: hsl(224, 20%, 94%); + --color-gray-2: hsl(224, 6%, 77%); + --color-gray-3: hsl(224, 6%, 56%); + --color-gray-4: hsl(224, 7%, 36%); + --color-gray-5: hsl(224, 10%, 23%); + --color-gray-6: hsl(224, 14%, 16%); + --color-black: hsl(224, 10%, 10%); + + --hue-orange: 41; + --color-orange-low: hsl(var(--hue-orange), 39%, 22%); + --color-orange: hsl(var(--hue-orange), 82%, 63%); + --color-orange-high: hsl(var(--hue-orange), 82%, 87%); + --hue-green: 101; + --color-green-low: hsl(var(--hue-green), 39%, 22%); + --color-green: hsl(var(--hue-green), 82%, 63%); + --color-green-high: hsl(var(--hue-green), 82%, 80%); + --hue-blue: 234; + --color-blue-low: hsl(var(--hue-blue), 54%, 20%); + --color-blue: hsl(var(--hue-blue), 100%, 60%); + --color-blue-high: hsl(var(--hue-blue), 100%, 87%); + --hue-purple: 281; + --color-purple-low: hsl(var(--hue-purple), 39%, 22%); + --color-purple: hsl(var(--hue-purple), 82%, 63%); + --color-purple-high: hsl(var(--hue-purple), 82%, 89%); + --hue-red: 339; + --color-red-low: hsl(var(--hue-red), 39%, 22%); + --color-red: hsl(var(--hue-red), 82%, 63%); + --color-red-high: hsl(var(--hue-red), 82%, 87%); + + --color-accent-low: hsl(13, 75%, 30%); + --color-accent: hsl(13, 88%, 57%); + --color-accent-high: hsl(13, 100%, 78%); + + --color-text: var(--color-gray-1); + --color-text-dimmed: var(--color-gray-3); + --color-text-accent: var(--color-accent); + --color-text-invert: var(--color-black); + --color-text-accent-invert: var(--color-accent-high); + --color-bg: var(--color-black); + --color-bg-surface: var(--color-gray-5); + --color-bg-accent: var(--color-accent-high); + --color-border: var(--color-gray-2); + + --color-backdrop-overlay: hsla(223, 13%, 10%, 0.66); +} + +:root[data-color-mode="light"] { + --color-white: hsl(224, 10%, 10%); + --color-gray-1: hsl(224, 14%, 16%); + --color-gray-2: hsl(224, 10%, 23%); + --color-gray-3: hsl(224, 7%, 36%); + --color-gray-4: hsl(224, 6%, 56%); + --color-gray-5: hsl(224, 6%, 77%); + --color-gray-6: hsl(224, 20%, 94%); + --color-gray-7: hsl(224, 19%, 97%); + --color-black: hsl(0, 0%, 100%); + + --color-orange-high: hsl(var(--hue-orange), 80%, 25%); + --color-orange: hsl(var(--hue-orange), 90%, 60%); + --color-orange-low: hsl(var(--hue-orange), 90%, 88%); + --color-green-high: hsl(var(--hue-green), 80%, 22%); + --color-green: hsl(var(--hue-green), 90%, 46%); + --color-green-low: hsl(var(--hue-green), 85%, 90%); + --color-blue-high: hsl(var(--hue-blue), 80%, 30%); + --color-blue: hsl(var(--hue-blue), 90%, 60%); + --color-blue-low: hsl(var(--hue-blue), 88%, 90%); + --color-purple-high: hsl(var(--hue-purple), 90%, 30%); + --color-purple: hsl(var(--hue-purple), 90%, 60%); + --color-purple-low: hsl(var(--hue-purple), 80%, 90%); + --color-red-high: hsl(var(--hue-red), 80%, 30%); + --color-red: hsl(var(--hue-red), 90%, 60%); + --color-red-low: hsl(var(--hue-red), 80%, 90%); + + --color-accent-high: hsl(13, 75%, 26%); + --color-accent: hsl(13, 88%, 60%); + --color-accent-low: hsl(13, 100%, 89%); + + --color-text-accent: var(--color-accent); + --color-text-dimmed: var(--color-gray-4); + --color-text-invert: var(--color-black); + --color-text-accent-invert: var(--color-accent-low); + --color-bg-surface: var(--color-gray-6); + --color-bg-accent: var(--color-accent); + + --color-backdrop-overlay: hsla(225, 9%, 36%, 0.66); +} diff --git a/cloud/web/src/ui/style/token/font.css b/cloud/web/src/ui/style/token/font.css new file mode 100644 index 000000000..24b2db3f2 --- /dev/null +++ b/cloud/web/src/ui/style/token/font.css @@ -0,0 +1,20 @@ +:root { + --font-size-2xs: 0.6875rem; + --font-size-xs: 0.75rem; + --font-size-sm: 0.8125rem; + --font-size-md: 0.9375rem; + --font-size-lg: 1.125rem; + --font-size-xl: 1.25rem; + --font-size-2xl: 1.5rem; + --font-size-3xl: 1.875rem; + --font-size-4xl: 2.25rem; + --font-size-5xl: 3rem; + --font-size-6xl: 3.75rem; + --font-size-7xl: 4.5rem; + --font-size-8xl: 6rem; + --font-size-9xl: 8rem; + --font-mono: IBM Plex Mono, monospace; + --font-sans: Rubik, sans-serif; + + --font-line-height: 1.75; +} diff --git a/cloud/web/src/ui/style/token/reset.css b/cloud/web/src/ui/style/token/reset.css new file mode 100644 index 000000000..f4aa1a0a9 --- /dev/null +++ b/cloud/web/src/ui/style/token/reset.css @@ -0,0 +1,212 @@ +* { + margin: 0; + padding: 0; + font: inherit; +} + +*, +*::before, +*::after { + box-sizing: border-box; + border-width: 0; + border-style: solid; + border-color: var(--global-color-border, currentColor); +} + +html { + line-height: 1.5; + --font-fallback: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -moz-tab-size: 4; + tab-size: 4; + font-family: var(--global-font-body, var(--font-fallback)); +} + +hr { + height: 0; + color: inherit; + border-top-width: 1px; +} + +body { + height: 100%; + line-height: inherit; +} + +img { + border-style: none; +} + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + vertical-align: middle; +} + +img, +video { + max-width: 100%; + height: auto; +} + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +ol, +ul { + list-style: none; +} + +code, +kbd, +pre, +samp { + font-size: 1em; +} + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; + background-color: transparent; + background-image: none; +} + +button, +input, +optgroup, +select, +textarea { + color: inherit; +} + +button, +select { + text-transform: none; +} + +table { + text-indent: 0; + border-color: inherit; + border-collapse: collapse; +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + color: var(--global-color-placeholder, #9ca3af); +} + +textarea { + resize: vertical; +} + +summary { + display: list-item; +} + +small { + font-size: 80%; +} + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +dialog { + padding: 0; +} + +a { + color: inherit; + text-decoration: inherit; +} + +abbr:where([title]) { + text-decoration: underline dotted; +} + +b, +strong { + font-weight: bolder; +} + +code, +kbd, +samp, +pre { + font-size: 1em; + --font-mono-fallback: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New"; + font-family: var(--global-font-mono, var(--font-fallback)); +} + +input[type="text"], +input[type="email"], +input[type="search"], +input[type="password"] { + -webkit-appearance: none; + -moz-appearance: none; +} + +input[type="search"] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +::-webkit-search-decoration, +::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +input[type="number"] { + -moz-appearance: textfield; +} + +:-moz-ui-invalid { + box-shadow: none; +} + +:-moz-focusring { + outline: auto; +} diff --git a/cloud/web/src/ui/style/token/space.css b/cloud/web/src/ui/style/token/space.css new file mode 100644 index 000000000..b1e492f49 --- /dev/null +++ b/cloud/web/src/ui/style/token/space.css @@ -0,0 +1,38 @@ +:root { + --space-0: 0; + --space-px: 1px; + --space-0-5: 0.125rem; + --space-1: 0.25rem; + --space-1-5: 0.375rem; + --space-2: 0.5rem; + --space-2-5: 0.625rem; + --space-3: 0.75rem; + --space-3-5: 0.875rem; + --space-4: 1rem; + --space-4-5: 1.125rem; + --space-5: 1.25rem; + --space-6: 1.5rem; + --space-7: 1.75rem; + --space-8: 2rem; + --space-9: 2.25rem; + --space-10: 2.5rem; + --space-11: 2.75rem; + --space-12: 3rem; + --space-14: 3.5rem; + --space-16: 4rem; + --space-20: 5rem; + --space-24: 6rem; + --space-28: 7rem; + --space-32: 8rem; + --space-36: 9rem; + --space-40: 10rem; + --space-44: 11rem; + --space-48: 12rem; + --space-52: 13rem; + --space-56: 14rem; + --space-60: 15rem; + --space-64: 16rem; + --space-72: 18rem; + --space-80: 20rem; + --space-96: 24rem; +} |
