Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/globals.css
T

1144 lines
33 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import "tailwindcss";
/* Subframe design-system theme tokens (generated; see .subframe/sync.json). */
@import "./ui/theme.css";
@custom-variant dark (&:is(.dark *));
@config '../../../tailwind.config.ts';
/*
Subframe's theme.css sets every typography token to "Instrument Sans" but the
Subframe sync never brought the actual font over, so all Subframe-styled text
fell back to the browser serif. Self-host the font (no runtime third-party
request — keeps the EU/privacy posture) and make it the default family with a
clean sans fallback so text renders correctly even before the font loads.
Variable font (weight 400–700); files in apps/web/public/fonts/.
*/
@font-face {
font-family: "Instrument Sans";
font-style: normal;
font-weight: 400 700;
font-stretch: 100%;
font-display: swap;
src: url("/fonts/instrument-sans-latin.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
U+FEFF, U+FFFD;
}
@font-face {
font-family: "Instrument Sans";
font-style: normal;
font-weight: 400 700;
font-stretch: 100%;
font-display: swap;
src: url("/fonts/instrument-sans-latin-ext.woff2") format("woff2");
unicode-range:
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/*
Some synced Subframe components and legacy theme presets still reference
Inter directly (`font-['Inter']`) or through `--font-inter`. Keep those
references metric-compatible with the app font instead of falling back to the
browser/system stack during navigation.
*/
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 400 700;
font-stretch: 100%;
font-display: swap;
src: url("/fonts/instrument-sans-latin.woff2") format("woff2");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
U+FEFF, U+FFFD;
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 400 700;
font-stretch: 100%;
font-display: swap;
src: url("/fonts/instrument-sans-latin-ext.woff2") format("woff2");
unicode-range:
U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@theme {
--default-font-family: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-inter: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-sans: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
/*
Product surfaces must never fall back to the browser's serif default when the
self-hosted font is still loading or unavailable. Subframe typography classes
reference individual font variables, so bind the complete product type scale
to one resilient product stack at the document boundary.
*/
.font-product {
--product-font-family: "Instrument Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-inter: var(--product-font-family);
--font-sans: var(--product-font-family);
--font-title-hero: var(--product-font-family);
--font-title-page: var(--product-font-family);
--font-subtitle: var(--product-font-family);
--font-heading-: var(--product-font-family);
--font-body-extra-small-regular-150: var(--product-font-family);
--font-body-small-medium-150: var(--product-font-family);
--font-body-default-medium-150: var(--product-font-family);
--font-body-large: var(--product-font-family);
--font-body-small-regular-150: var(--product-font-family);
--font-body-default-regular-150: var(--product-font-family);
--font-body-extra-small-medium-150: var(--product-font-family);
--font-body-extra-small-semibold-150: var(--product-font-family);
--font-body-small-semibold-150: var(--product-font-family);
--font-body-default-semibold-150: var(--product-font-family);
--font-body-small-medium-0: var(--product-font-family);
--font-body-extra-small-semibold-0: var(--product-font-family);
--font-body-extra-small-medium-0: var(--product-font-family);
--font-body-extra-small-regular-0: var(--product-font-family);
--font-body-small-regular-0: var(--product-font-family);
--font-body-small-semibold-0: var(--product-font-family);
--font-body-default-regular-0: var(--product-font-family);
--font-body-default-medium-0: var(--product-font-family);
--font-body-default-semibold-0: var(--product-font-family);
--font-body-large-0: var(--product-font-family);
--font-subtitle-0: var(--product-font-family);
--font-heading-0: var(--product-font-family);
font-family: var(--product-font-family);
}
/*
Solid-neutral surfaces (Button/IconButton variant="neutral", BadgeFeedback/Tag
solid-neutral) shipped with default grey-800 / active grey-900 — a washed-out
"almost black" that visibly clashes next to the primary button's grey-900.
Mirror the primary solid ramp instead (default grey-900, hover grey-700,
active grey-800) so all solid dark controls share the same black. theme.css is
overwritten on every Subframe sync, so the override lives here.
*/
@theme {
--color-surface-feedback-solid-neutral: var(--color-neutral-900);
--color-surface-feedback-solid-neutral-hover: var(--color-neutral-700);
--color-surface-feedback-solid-neutral-active: var(--color-neutral-800);
}
/*
Local fix (D-D0a): Subframe's "default" heading style is the token `--text-heading-`
(trailing dash). Tailwind v4 does NOT emit a `text-heading-`/`font-heading-` utility
for a token whose name ends in `-`, so every Subframe page that uses `text-heading-`
rendered unstyled (16px/400 fallback) instead of 24px/500. The token IS registered in
the twMerge list (app/ui/utils.ts), only the CSS was missing. Re-create both utilities
from the existing token values. theme.css is overwritten on every Subframe sync, so the
fix lives here in globals.css.
*/
@layer utilities {
.text-heading- {
font-size: var(--text-heading-);
font-weight: var(--text-heading---font-weight);
line-height: var(--text-heading---line-height);
letter-spacing: var(--text-heading---letter-spacing);
}
.font-heading- {
font-family: var(--font-heading-);
}
}
/*
Tailwind v4 preflight resets buttons to `cursor: default`. Every clickable
control in the app should signal interactivity like a link does; disabled
controls keep the default cursor (components may override with not-allowed).
*/
@layer base {
button:not(:disabled),
[role="button"]:not([aria-disabled="true"]),
input[type="submit"]:not(:disabled),
input[type="checkbox"]:not(:disabled),
input[type="radio"]:not(:disabled),
select:not(:disabled),
summary {
cursor: pointer;
}
}
/*
Subframe's "-0" text tokens used line-height equal to font-size. That clips
glyphs with ascenders/descenders or umlauts in tight containers (e.g. "Ü", "g",
"p"). Keep the font sizes/weights but give these tokens a usable line box
globally instead of patching individual screens.
*/
@layer base {
:root {
--text-body-extra-small-regular-0--line-height: 16px;
--text-body-extra-small-medium-0--line-height: 16px;
--text-body-extra-small-semibold-0--line-height: 16px;
--text-body-small-regular-0--line-height: 18px;
--text-body-small-medium-0--line-height: 18px;
--text-body-small-semibold-0--line-height: 18px;
--text-body-default-regular-0--line-height: 22px;
--text-body-default-medium-0--line-height: 22px;
--text-body-default-semibold-0--line-height: 22px;
--text-body-large-0--line-height: 26px;
--text-subtitle-0--line-height: 40px;
--text-heading-0--line-height: 32px;
}
}
/*
@tailwindcss/forms paints a 1px blue ring (box-shadow, not outline) on every
focused input. The design system shows focus on the surrounding field instead —
TextInput, SearchInput and the filter bar all carry `focus-within:shadow-focus`
on their wrapper — so the plugin ring draws a second, differently coloured
border inside the one that is already there.
Removed for the controls that carry the kit marker class, not for inputs in
general: a bare input outside the design system still needs a visible focus
indicator, and dropping it there would be an accessibility regression.
*/
@layer base {
.subframe-text-input-control:focus,
.subframe-text-input-control:focus-visible {
box-shadow: none;
}
}
@layer base {
.subframe-text-input-control:-webkit-autofill,
.subframe-text-input-control:-webkit-autofill:hover,
.subframe-text-input-control:-webkit-autofill:focus,
.subframe-text-input-control:-webkit-autofill:active {
-webkit-box-shadow: 0 0 0 1000px var(--color-surface-neutral-primary) inset !important;
-webkit-text-fill-color: var(--color-text-neutral-secondary) !important;
caret-color: var(--color-text-neutral-secondary);
transition: background-color 9999s ease-out 0s;
}
}
/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
.typography {
max-width: 65ch;
color: var(--color-foreground);
}
.typography h1:not(.not-typography h1) {
scroll-margin: calc(var(--spacing) * 20);
font-size: var(--text-4xl);
line-height: var(--text-4xl--line-height);
font-weight: 800;
letter-spacing: var(--tracking-tight);
}
.typography h2:not(.not-typography h2) {
scroll-margin: calc(var(--spacing) * 20);
border-bottom: 1px solid var(--color-border);
padding-bottom: calc(var(--spacing) * 2);
font-size: var(--text-3xl);
line-height: var(--text-3xl--line-height);
font-weight: 600;
letter-spacing: var(--tracking-tight);
margin-top: calc(var(--spacing) * 12);
}
.typography h2:not(.not-typography h2):first-child {
margin-top: 0;
}
.typography h3:not(.not-typography h3) {
scroll-margin: calc(var(--spacing) * 20);
font-size: var(--text-2xl);
line-height: var(--text-2xl--line-height);
font-weight: 600;
letter-spacing: var(--tracking-tight);
margin-top: calc(var(--spacing) * 12);
}
.typography h3:not(.not-typography h3):first-child {
margin-top: 0;
}
.typography h4:not(.not-typography h4) {
scroll-margin: calc(var(--spacing) * 20);
font-size: var(--text-xl);
line-height: var(--text-xl--line-height);
font-weight: 600;
letter-spacing: var(--tracking-tight);
margin-top: calc(var(--spacing) * 12);
}
.typography h4:not(.not-typography h4):first-child {
margin-top: 0;
}
.typography h5:not(.not-typography h5) {
scroll-margin: calc(var(--spacing) * 20);
font-size: var(--text-lg);
line-height: var(--text-lg--line-height);
font-weight: 600;
letter-spacing: var(--tracking-tight);
margin-top: calc(var(--spacing) * 12);
}
.typography h5:not(.not-typography h5):first-child {
margin-top: 0;
}
.typography h6:not(.not-typography h6) {
scroll-margin: calc(var(--spacing) * 20);
font-size: var(--text-base);
line-height: var(--text-base--line-height);
font-weight: 600;
letter-spacing: var(--tracking-tight);
margin-top: calc(var(--spacing) * 12);
}
.typography h6:not(.not-typography h6):first-child {
margin-top: 0;
}
.typography h1:not(.not-typography h1) + p,
.typography h2:not(.not-typography h2) + p,
.typography h3:not(.not-typography h3) + p,
.typography h4:not(.not-typography h4) + p,
.typography h5:not(.not-typography h5) + p,
.typography h6:not(.not-typography h6) + p {
margin-top: 0;
}
.typography p:not(.not-typography p) {
line-height: 1.75;
}
.typography p:not(.not-typography p):not(:first-child) {
margin-top: calc(var(--spacing) * 6);
}
.typography li:not(.not-typography li) {
line-height: 1.75;
}
.typography a:not(.not-typography a) {
font-weight: 500;
color: var(--color-primary);
text-decoration: underline;
text-underline-offset: var(--spacing);
overflow-wrap: anywhere;
}
.typography blockquote:not(.not-typography blockquote) {
margin-top: calc(var(--spacing) * 6);
border-left: 2px solid var(--color-border);
padding-left: calc(var(--spacing) * 6);
font-style: italic;
}
.typography table:not(.not-typography table) {
margin-top: calc(var(--spacing) * 6);
margin-bottom: calc(var(--spacing) * 6);
width: 100%;
overflow-y: auto;
}
.typography table:not(.not-typography table) thead tr {
margin: 0;
border-top: 1px solid var(--color-border);
padding: 0;
}
.typography table:not(.not-typography table) thead tr:nth-child(even) {
background-color: var(--color-muted);
}
.typography table:not(.not-typography table) th {
border: 1px solid var(--color-border);
padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4);
text-align: left;
font-weight: 700;
}
.typography table:not(.not-typography table) th[align="center"] {
text-align: center;
}
.typography table:not(.not-typography table) th[align="right"] {
text-align: right;
}
.typography table:not(.not-typography table) tbody tr {
margin: 0;
border-top: 1px solid var(--color-border);
padding: 0;
}
.typography table:not(.not-typography table) tbody tr:nth-child(even) {
background-color: var(--color-muted);
}
.typography table:not(.not-typography table) td {
border: 1px solid var(--color-border);
padding: calc(var(--spacing) * 2) calc(var(--spacing) * 4);
text-align: left;
}
.typography table:not(.not-typography table) td[align="center"] {
text-align: center;
}
.typography table:not(.not-typography table) td[align="right"] {
text-align: right;
}
.typography ul:not(.not-typography ul) {
margin-top: calc(var(--spacing) * 6);
margin-left: calc(var(--spacing) * 6);
list-style: disc;
}
.typography ul:not(.not-typography ul) > li {
margin-top: calc(var(--spacing) * 2);
}
.typography ul:not(.not-typography ul) p {
margin-top: 0;
margin-bottom: 0;
display: inline;
}
.typography ol:not(.not-typography ol) {
margin-top: calc(var(--spacing) * 6);
margin-left: calc(var(--spacing) * 6);
list-style: decimal;
}
.typography ol:not(.not-typography ol) > li {
margin-top: calc(var(--spacing) * 2);
}
.typography ol:not(.not-typography ol) p {
margin-top: 0;
margin-bottom: 0;
display: inline;
}
.typography pre:not(.not-typography pre) {
background-color: var(--color-muted);
border-radius: calc(var(--radius) - 2px);
padding: calc(var(--spacing) * 4);
margin-top: calc(var(--spacing) * 6);
margin-bottom: calc(var(--spacing) * 6);
font-size: var(--text-sm);
line-height: var(--text-sm--line-height);
overflow-y: auto;
}
.typography code:not(pre code):not(.not-typography code) {
position: relative;
border-radius: var(--radius);
background-color: var(--color-muted);
padding: calc(var(--spacing) * 0.2) calc(var(--spacing) * 0.3);
font-family: var(--font-mono);
font-size: var(--text-sm);
line-height: var(--text-sm--line-height);
font-weight: 600;
}
.typography .lead:not(.not-typography .lead) {
font-size: var(--text-xl);
line-height: var(--text-xl--line-height);
color: var(--color-muted-foreground);
}
.typography .large:not(.not-typography .large) {
font-size: var(--text-lg);
line-height: var(--text-lg--line-height);
font-weight: 600;
}
.typography .small:not(.not-typography .small) {
font-size: var(--text-sm);
line-height: 1;
font-weight: 500;
}
.typography .muted:not(.not-typography .muted) {
font-size: var(--text-sm);
line-height: var(--text-sm--line-height);
color: var(--color-muted-foreground);
}
.typography img:not(.not-typography img),
.typography picture:not(.not-typography picture),
.typography video:not(.not-typography video) {
margin-top: calc(var(--spacing) * 6);
margin-bottom: calc(var(--spacing) * 6);
}
.typography picture > img:not(.not-typography picture > img) {
margin-top: 0;
margin-bottom: 0;
}
.typography kbd:not(.not-typography kbd) {
border-radius: calc(var(--radius) - 2px);
background-color: var(--color-muted);
padding: calc(var(--spacing) * 0.5) calc(var(--spacing) * 1.5);
font-size: var(--text-xs);
line-height: var(--text-xs--line-height);
font-weight: 600;
}
.typography hr {
margin-top: calc(var(--spacing) * 10);
margin-bottom: calc(var(--spacing) * 10);
}
.typography dl:not(.not-typography dl) {
margin-top: calc(var(--spacing) * 6);
margin-bottom: calc(var(--spacing) * 6);
}
.typography dl:not(.not-typography dl) dt {
font-weight: 600;
margin-top: calc(var(--spacing) * 6);
letter-spacing: var(--tracking-tight);
}
.typography dl:not(.not-typography dl) dt:first-child {
margin-top: 0;
}
.typography details:not(.not-typography details) {
margin-top: calc(var(--spacing) * 6);
}
.typography details:not(.not-typography details) summary {
cursor: pointer;
font-weight: 600;
margin-top: calc(var(--spacing) * 6);
letter-spacing: var(--tracking-tight);
}
.typography details:not(.not-typography details) p:first-of-type {
margin-top: calc(var(--spacing) * 2);
}
.typography mark:not(.not-typography mark) {
background-color: var(--color-yellow-300);
}
.typography small:not(.not-typography small) {
font-size: var(--text-xs);
line-height: 1;
}
/*
---break---
*/
@media (min-width: 1024px) {
.typography h1:not(.not-typography h1) {
font-size: var(--text-5xl);
line-height: var(--text-5xl--line-height);
}
}
}
@utility tooltip {
@apply invisible absolute;
.has-tooltip:hover & {
@apply visible z-50;
}
}
@utility has-tooltip {
&:hover .tooltip {
@apply visible z-50;
}
}
@utility base-spinner {
position: relative;
overflow: hidden;
&:before {
content: "";
box-sizing: border-box;
position: absolute;
background-color: inherit;
width: 100%;
height: 100%;
display: block;
z-index: 1;
top: 0;
left: 0;
}
&:after {
content: "";
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.45);
border-top-color: inherit;
animation: spinner 0.6s linear infinite;
z-index: 2;
}
}
@utility loader {
border-top-color: #5a67d8;
-webkit-animation: spinner 1.5s linear infinite;
animation: spinner 1.5s linear infinite;
}
@utility drop {
align-items: center;
justify-content: center;
padding: 1rem;
transition: background-color 0.2s ease-in-out;
}
@utility uploadmyfile {
display: none;
}
@utility tiptap {
:first-child {
margin-top: 0;
}
ul {
@apply list-disc;
padding: 0 1rem;
margin: 1.25rem 1rem 1.25rem 0.4rem;
li p {
margin-top: 0.25em;
margin-bottom: 0.25em;
}
}
ol {
@apply list-decimal;
padding: 0 1rem;
margin: 1.25rem 1rem 1.25rem 0.4rem;
li p {
margin-top: 0.25em;
margin-bottom: 0.25em;
}
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
margin-top: 2.5rem;
text-wrap: pretty;
}
h1,
h2 {
margin-top: 3.5rem;
margin-bottom: 1.5rem;
}
h1 {
font-size: 1.4rem;
}
h2 {
font-size: 1.2rem;
}
h3 {
font-size: 1.1rem;
}
h4,
h5,
h6 {
font-size: 1rem;
}
code {
background-color: hsl(var(--muted));
border-radius: 0.4rem;
color: hsl(var(--foreground));
font-size: 0.85rem;
padding: 0.25em 0.3em;
}
pre {
background: hsl(var(--foreground));
border-radius: 0.5rem;
color: hsl(var(--background));
font-family: "JetBrainsMono", monospace;
margin: 1.5rem 0;
padding: 0.75rem 1rem;
code {
background: none;
color: inherit;
font-size: 0.8rem;
padding: 0;
}
}
blockquote {
border-left: 3px solid hsl(var(--border));
margin: 1.5rem 0;
padding-left: 1rem;
}
hr {
border: none;
border-top: 1px solid hsl(var(--border));
margin: 2rem 0;
}
}
@utility scrollbar-hidden {
scrollbar-width: none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
}
@layer utilities {
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
}
:root {
--background: hsl(0 0% 100%);
--foreground: hsl(240 10% 3.9%);
--muted: hsl(240 4.8% 95.9%);
--muted-foreground: hsl(240 3.8% 46.1%);
--popover: hsl(0 0% 100%);
--popover-foreground: hsl(240 10% 3.9%);
--card: hsl(0 0% 100%);
--card-foreground: hsl(240 10% 3.9%);
--border: hsl(240 5.9% 90%);
--input: hsl(240 5.9% 90%);
--primary: hsl(240 5.9% 10%);
--primary-foreground: hsl(0 0% 98%);
--secondary: hsl(240 4.8% 95.9%);
--secondary-foreground: hsl(240 5.9% 10%);
--accent: hsl(240 4.8% 95.9%);
--accent-foreground: hsl(240 5.9% 10%);
--destructive: hsl(0 84.2% 60.2%);
--destructive-foreground: hsl(0 0% 98%);
--ring: hsl(240 5.9% 10%);
--radius: 0.5rem;
/* Subframe SidebarWithSections palette (light): map the shadcn sidebar tokens
onto the Subframe surface/text/border tokens so the (light) tenant sidebar
matches the design-system component. Dark `--sidebar-*` (admin + dark mode)
stays as-is — Subframe's surface tokens are light-only. */
--sidebar-background: var(--color-surface-neutral-secondary);
--sidebar-foreground: var(--color-text-neutral-secondary);
--sidebar-primary: hsl(240 5.9% 10%);
--sidebar-primary-foreground: hsl(0 0% 98%);
--sidebar-accent: var(--color-surface-neutral-tertiary);
--sidebar-accent-foreground: var(--color-text-neutral-primary);
--sidebar-border: var(--color-border-default);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
--sidebar: var(--color-surface-neutral-secondary);
--chart-1: 221.2 83.2% 53.3%;
--chart-2: 212 95% 68%;
--chart-3: 216 92% 60%;
--chart-4: 210 98% 78%;
--chart-5: 212 97% 87%;
}
.dark {
--background: hsl(240 10% 3.9%);
--foreground: hsl(0 0% 98%);
--muted: hsl(240 3.7% 15.9%);
--muted-foreground: hsl(240 5% 64.9%);
--popover: hsl(240 10% 3.9%);
--popover-foreground: hsl(0 0% 98%);
--card: hsl(240 10% 3.9%);
--card-foreground: hsl(0 0% 98%);
--border: hsl(240 3.7% 15.9%);
--input: hsl(240 3.7% 15.9%);
--primary: hsl(0 0% 98%);
--primary-foreground: hsl(240 5.9% 10%);
--secondary: hsl(240 3.7% 15.9%);
--secondary-foreground: hsl(0 0% 98%);
--accent: hsl(240 3.7% 15.9%);
--accent-foreground: hsl(0 0% 98%);
--destructive: hsl(0 62.8% 30.6%);
--destructive-foreground: hsl(0 0% 98%);
--ring: hsl(240 4.9% 83.9%);
--sidebar-background: hsl(240 10% 3.9%);
--sidebar-foreground: hsl(240 4.8% 95.9%);
--sidebar-primary: hsl(224.3 76.3% 48%);
--sidebar-primary-foreground: hsl(0 0% 100%);
--sidebar-accent: hsl(240 3.7% 15.9%);
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
--sidebar-border: hsl(240 3.7% 15.9%);
--sidebar-ring: hsl(217.2 91.2% 59.8%);
--sidebar: hsl(240 5.9% 10%);
--chart-1: 221.2 83.2% 53.3%;
--chart-2: 212 95% 68%;
--chart-3: 216 92% 60%;
--chart-4: 210 98% 78%;
--chart-5: 212 97% 87%;
}
@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
--breakpoint-3xl: 120rem;
--breakpoint-4xl: 140rem;
/*
---break---
*/
@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
/*
---break---
*/
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply text-foreground overscroll-y-none bg-transparent;
}
}
/* Browser-local accessibility preference: remove optional motion and blur. */
html[data-hg-visual-effects="off"] {
scroll-behavior: auto !important;
}
html[data-hg-visual-effects="off"] *,
html[data-hg-visual-effects="off"] *::before,
html[data-hg-visual-effects="off"] *::after {
animation: none !important;
transition: none !important;
scroll-behavior: auto !important;
}
html[data-hg-visual-effects="off"] [class*="blur"],
html[data-hg-visual-effects="off"] [style*="blur("] {
filter: none !important;
-webkit-backdrop-filter: none !important;
backdrop-filter: none !important;
}
/* Full-width workflow drawer motion: the panel starts completely beyond the
right viewport edge and visibly travels left onto the canvas. */
@keyframes hg-drawer-enter-from-right {
from {
transform: translate3d(105%, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes hg-drawer-exit-to-right {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(105%, 0, 0);
}
}
@keyframes hg-drawer-backdrop-enter {
from {
background-color: rgb(0 0 0 / 0%);
-webkit-backdrop-filter: blur(0);
backdrop-filter: blur(0);
}
to {
background-color: rgb(0 0 0 / 35%);
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
}
}
@keyframes hg-drawer-backdrop-exit {
from {
background-color: rgb(0 0 0 / 35%);
-webkit-backdrop-filter: blur(4px);
backdrop-filter: blur(4px);
}
to {
background-color: rgb(0 0 0 / 0%);
-webkit-backdrop-filter: blur(0);
backdrop-filter: blur(0);
}
}
.hg-drawer-backdrop[data-state="open"] {
animation: hg-drawer-backdrop-enter 300ms ease-out both;
}
.hg-drawer-backdrop[data-state="closed"] {
animation: hg-drawer-backdrop-exit 300ms ease-out both;
}
.hg-drawer-full-from-right[data-state="open"] {
animation: hg-drawer-enter-from-right 440ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.hg-drawer-full-from-right[data-state="closed"] {
animation: hg-drawer-exit-to-right 440ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@media (prefers-reduced-motion: reduce) {
.hg-drawer-backdrop,
.hg-drawer-full-from-right {
animation: none !important;
}
}
/* Keep centered dialogs stable when third-party widgets inject global styles. */
[data-slot="dialog-content"][data-positioning="centered"] {
position: fixed !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
}
[data-slot="dialog-overlay"] {
position: fixed !important;
inset: 0 !important;
}
/*
* VD-MCP connect pill — idle it stays a plain bordered button. On hover (and on
* keyboard focus) the brand gold sweeps around the border and the client marks
* ride past on a 3D conveyor showing every supported client, not just the three
* that fit. Pure decoration: everything below is inert under reduced motion.
*/
/*
* The sweep is back to the original form: one conic gradient turning at a
* constant angular rate. Thickness and the dual glow stay at the tuned values.
*/
@property --hg-mcp-angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@keyframes hg-mcp-border-sweep {
to {
--hg-mcp-angle: 360deg;
}
}
.hg-mcp-pill::before {
content: "";
position: absolute;
inset: -4.05px;
z-index: 1;
border-radius: inherit;
padding: 4.05px;
/* Tight hot glow plus a wide soft one — this is what reads as sparkle. */
filter: drop-shadow(0 0 2px rgb(255 236 179 / 0.9)) drop-shadow(0 0 7px rgb(241 183 41 / 0.6));
background: conic-gradient(
from var(--hg-mcp-angle),
rgb(241 183 41 / 0) 0deg,
rgb(241 183 41 / 0.15) 40deg,
rgb(241 183 41 / 1) 80deg,
rgb(255 236 179 / 1) 100deg,
rgb(241 183 41 / 1) 120deg,
rgb(241 183 41 / 0.15) 160deg,
rgb(241 183 41 / 0) 200deg
);
/* Ring-only fill: the mask keeps the padding box and drops the content box. */
-webkit-mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
-webkit-mask-composite: xor;
mask:
linear-gradient(#000 0 0) content-box,
linear-gradient(#000 0 0);
mask-composite: exclude;
opacity: 0;
pointer-events: none;
transition: opacity 180ms ease;
}
.hg-mcp-pill:hover::before,
.hg-mcp-pill:focus-visible::before {
opacity: 1;
animation: hg-mcp-border-sweep 2.4s linear infinite;
}
/* Two identical mark copies, so -50% -> 0 loops without a seam. */
@keyframes hg-mcp-marks-ride {
from {
transform: translate3d(-50%, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes hg-mcp-mark-flip {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
.hg-mcp-pill {
position: relative;
isolation: isolate;
}
.hg-mcp-marks {
display: block;
/* Three marks wide (3 x 14px + 2 x 6px gap); the rest rides in from outside. */
width: 3.375rem;
overflow: hidden;
perspective: 220px;
}
.hg-mcp-pill:hover .hg-mcp-marks,
.hg-mcp-pill:focus-visible .hg-mcp-marks {
-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 22%, #000 78%, transparent 100%);
mask-image: linear-gradient(90deg, transparent 0, #000 22%, #000 78%, transparent 100%);
}
/*
* At rest the track is parked on the second copy's first mark, which is where
* the ride animation starts and ends — so hovering picks up exactly here with
* no jump. Parking it explicitly rather than relying on a paused animation's
* frame 0: a paused animation still advances its clock in Chrome and ends up
* holding an arbitrary offset that slices the marks mid-glyph.
*/
.hg-mcp-marks-track {
display: flex;
width: max-content;
align-items: center;
transform: translate3d(-50%, 0, 0);
transform-style: preserve-3d;
/* Lets the marks glide back into place when the pointer leaves mid-ride. */
transition: transform 260ms ease-out;
}
/* Margin instead of flex gap: gap would leave half a gap unaccounted for in
the 50% loop period and the conveyor would jump 3px every cycle. */
.hg-mcp-marks-track > * {
margin-right: 0.375rem;
flex: none;
backface-visibility: visible;
}
.hg-mcp-pill:hover .hg-mcp-marks-track,
.hg-mcp-pill:focus-visible .hg-mcp-marks-track {
animation: hg-mcp-marks-ride 3.47s linear infinite;
transition: none;
}
.hg-mcp-pill:hover .hg-mcp-marks-track > *,
.hg-mcp-pill:focus-visible .hg-mcp-marks-track > * {
animation: hg-mcp-mark-flip 6.48s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
.hg-mcp-pill::before,
.hg-mcp-marks-track,
.hg-mcp-marks-track > * {
animation: none !important;
}
.hg-mcp-pill:hover::before,
.hg-mcp-pill:focus-visible::before {
/* Keep the affordance, drop the motion. */
opacity: 1;
background: rgb(241 183 41 / 0.9);
}
}
/* Kanban drag & drop: while a card is in hand the pointer leaves the tile it
started on, so a `cursor-grabbing` class on the card alone would flicker back
to the default arrow. SortableKanbanBoard sets this class on <html> for the
duration of the drag and the grabbing fist wins everywhere, including over
the drop targets and the text inside them. */
html.hg-kanban-dragging,
html.hg-kanban-dragging * {
cursor: grabbing !important;
}