/* * WrNexus UI stylesheet. Served once at /__wrnexus/ui.css. Every value is a theme * token (var(--wrn-*)), so components restyle instantly when the theme changes. * Override any of these classes in your own CSS (it loads after ui.css). */ /* SSR visibility fallback. The reactive runtime also manages `data-show`, but * server-rendered components must not flash or permanently expose inactive * branches before hydration (for example an action's link and button at once). */ [data-show=""], [data-show="false"], [data-show="0"], [data-show="null"], [data-show="undefined"] { display: none !important; } /* --- Layout --------------------------------------------------------------- */ .wrn-container { width: 100%; max-width: 960px; margin-inline: auto; padding-inline: 1rem; } .wrn-stack { display: flex; flex-direction: column; } .wrn-hstack { display: flex; flex-direction: row; flex-wrap: wrap; } .wrn-grid { display: grid; } .wrn-spacer { flex: 1 1 auto; } .wrn-divider { border: 0; border-top: 1px solid var(--wrn-color-border); margin: 0; } /* gap scale (shared by stack / hstack / grid) */ .wrn-gap-0 { gap: 0; } .wrn-gap-1 { gap: 0.25rem; } .wrn-gap-2 { gap: 0.5rem; } .wrn-gap-3 { gap: 0.75rem; } .wrn-gap-4 { gap: 1rem; } .wrn-gap-5 { gap: 1.5rem; } .wrn-gap-6 { gap: 2rem; } .wrn-gap-8 { gap: 3rem; } .wrn-items-start { align-items: flex-start; } .wrn-items-center { align-items: center; } .wrn-items-end { align-items: flex-end; } .wrn-items-stretch { align-items: stretch; } .wrn-cols-1 { grid-template-columns: repeat(1, 1fr); } .wrn-cols-2 { grid-template-columns: repeat(2, 1fr); } .wrn-cols-3 { grid-template-columns: repeat(3, 1fr); } .wrn-cols-4 { grid-template-columns: repeat(4, 1fr); } .wrn-cols-5 { grid-template-columns: repeat(5, 1fr); } .wrn-cols-6 { grid-template-columns: repeat(6, 1fr); } @media (max-width: 640px) { .wrn-grid { grid-template-columns: 1fr; } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } } :where(button, a):focus-visible { outline: 2px solid var(--wrn-color-primary); outline-offset: 2px; } /* --- Component-system foundations --------------------------------------- */ .wrn-type { margin: 0; color: var(--wrn-color-text); } .wrn-type--display { font-size: clamp(2.25rem, 7vw, 4.75rem); line-height: 1.02; font-weight: 800; letter-spacing: -0.04em; } .wrn-type--heading { font-size: clamp(1.75rem, 4vw, 3rem); line-height: 1.1; font-weight: 750; letter-spacing: -0.025em; } .wrn-type--lead { font-size: clamp(1.05rem, 2vw, 1.25rem); line-height: 1.65; color: var(--wrn-color-muted); } .wrn-type--body { font-size: 1rem; line-height: 1.65; } .wrn-type--small { font-size: 0.875rem; line-height: 1.5; } .wrn-text--center { text-align: center; } .wrn-text--end { text-align: end; } .wrn-form { display: grid; gap: 1.25rem; width: 100%; } .wrn-form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; } .wrn-field, .wrn-fieldset { display: grid; gap: 0.45rem; min-width: 0; border: 0; padding: 0; margin: 0; } .wrn-label { color: var(--wrn-color-text); font-size: 0.875rem; font-weight: 650; line-height: 1.4; } .wrn-required, .wrn-field-message--error { color: var(--wrn-color-danger); } .wrn-optional, .wrn-field-message--help { color: var(--wrn-color-muted); font-weight: 400; } .wrn-field-message { margin: 0; font-size: 0.8125rem; line-height: 1.5; } .wrn-input:disabled { cursor: not-allowed; opacity: 0.58; } .wrn-input[aria-invalid="true"] { border-color: var(--wrn-color-danger); } .wrn-multiselect { min-height: 8rem; } .wrn-loading-button { min-height: 44px; } .wrn-overlay { position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center; padding: 1rem; background: rgb(0 0 0 / 0.55); backdrop-filter: blur(4px); } .wrn-dialog { width: min(100%, 32rem); max-height: calc(100dvh - 2rem); overflow: auto; padding: clamp(1.25rem, 4vw, 2rem); color: var(--wrn-color-text); background: var(--wrn-color-surface); border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); box-shadow: var(--wrn-shadow-1); } .wrn-dialog__title { margin: 0; font-size: 1.35rem; line-height: 1.25; } .wrn-dialog__description { margin: 0.75rem 0 0; color: var(--wrn-color-muted); line-height: 1.6; } .wrn-dialog__actions { display: flex; justify-content: flex-end; gap: 0.75rem; margin-top: 1.5rem; } .wrn-dialog__actions--wrap { flex-wrap: wrap; } .wrn-filter-bar { display: flex; align-items: end; justify-content: space-between; gap: 1rem; padding: 1rem; background: var(--wrn-color-surface); border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); } .wrn-filter-bar__controls { display: flex; flex: 1; flex-wrap: wrap; align-items: end; gap: 0.75rem; } .wrn-table--striped tbody tr:nth-child(even) { background: var(--wrn-color-surface-2); } .wrn-comparison-table { min-width: 42rem; } .wrn-desktop-nav > ul { display: flex; align-items: center; gap: 0.25rem; } .wrn-mobile-nav { display: none; } .wrn-mobile-nav__panel { position: fixed; inset: 4rem 1rem auto; z-index: 100; max-height: calc(100dvh - 5rem); overflow: auto; padding: 1rem; background: var(--wrn-color-surface); border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); box-shadow: var(--wrn-shadow-1); } .wrn-eyebrow { color: var(--wrn-color-primary); font-size: 0.75rem; font-weight: 750; letter-spacing: 0.1em; text-transform: uppercase; } .wrn-auth-card > .wrn-eyebrow { justify-self: start; margin-bottom: 0.9rem; padding: 0.4rem 0.75rem; border: 1px solid color-mix(in srgb, var(--wrn-color-primary) 24%, transparent); border-radius: 999px; color: var(--wrn-color-primary); background: color-mix(in srgb, var(--wrn-color-primary) 9%, transparent); font-size: 0.7rem; font-weight: 750; letter-spacing: 0.08em; text-transform: uppercase; } .wrn-catalog-overlay .wrn-dialog { width: min(100%, 42rem); max-height: calc(100dvh - 2rem); overflow: auto; padding: clamp(1rem, 4vw, 1.5rem); color: var(--wrn-color-text); background: var(--wrn-color-surface); border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); box-shadow: 0 1.5rem 5rem rgb(0 0 0 / 0.3); } @media (max-width: 480px) { .wrn-catalog-action, .wrn-catalog-action > :where(a, button) { width: 100%; } .wrn-catalog-overlay { align-items: end; padding: 0; } .wrn-catalog-overlay .wrn-dialog { max-height: 92dvh; border-radius: var(--wrn-radius) var(--wrn-radius) 0 0; } } /* --- Motion system ------------------------------------------------------- * Applies to both Tailwind-authored and token-authored components. Motion is * intentionally limited to composited properties so interaction stays fluid. */ :root { --wrn-motion-fast: 120ms; --wrn-motion-base: 200ms; --wrn-motion-slow: 320ms; --wrn-ease-standard: cubic-bezier(0.2, 0, 0, 1); --wrn-ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1); } /* Tailwind v4 color bridge. Define the aliases at the document root so both * packaged components and application-authored pages/components inherit the * palette selected in wrnexus.config.ts. */ :root { --color-violet-50: color-mix(in srgb, var(--wrn-color-primary) 7%, white); --color-violet-100: color-mix(in srgb, var(--wrn-color-primary) 14%, white); --color-violet-200: color-mix(in srgb, var(--wrn-color-primary) 25%, white); --color-violet-300: color-mix(in srgb, var(--wrn-color-primary) 42%, white); --color-violet-400: color-mix(in srgb, var(--wrn-color-primary) 72%, white); --color-violet-500: var(--wrn-color-primary); --color-violet-600: var(--wrn-color-primary); --color-violet-700: var(--wrn-color-primary-hover); --color-violet-800: color-mix(in srgb, var(--wrn-color-primary-hover) 82%, black); --color-violet-900: color-mix(in srgb, var(--wrn-color-primary-hover) 65%, black); --color-violet-950: color-mix(in srgb, var(--wrn-color-primary-hover) 42%, black); --color-indigo-50: var(--color-violet-50); --color-indigo-100: var(--color-violet-100); --color-indigo-200: var(--color-violet-200); --color-indigo-300: var(--color-violet-300); --color-indigo-400: var(--color-violet-400); --color-indigo-500: var(--color-violet-500); --color-indigo-600: var(--color-violet-600); --color-indigo-700: var(--color-violet-700); --color-indigo-800: var(--color-violet-800); --color-indigo-900: var(--color-violet-900); --color-indigo-950: var(--color-violet-950); --color-blue-500: var(--wrn-color-info); --color-blue-600: var(--wrn-color-info); --color-blue-700: color-mix(in srgb, var(--wrn-color-info) 80%, black); --color-emerald-500: var(--wrn-color-success); --color-emerald-600: var(--wrn-color-success); --color-emerald-700: color-mix(in srgb, var(--wrn-color-success) 80%, black); --color-green-500: var(--wrn-color-success); --color-green-600: var(--wrn-color-success); --color-amber-500: var(--wrn-color-warning); --color-amber-600: var(--wrn-color-warning); --color-amber-700: color-mix(in srgb, var(--wrn-color-warning) 80%, black); --color-yellow-500: var(--wrn-color-warning); --color-red-400: color-mix(in srgb, var(--wrn-color-danger) 75%, white); --color-red-500: var(--wrn-color-danger); --color-red-600: var(--wrn-color-danger); --color-red-700: color-mix(in srgb, var(--wrn-color-danger) 80%, black); --color-rose-500: var(--wrn-color-danger); --color-rose-600: var(--wrn-color-danger); --color-rose-700: color-mix(in srgb, var(--wrn-color-danger) 80%, black); } /* Stable semantic helpers for application-authored markup. These deliberately * avoid spacing so applications remain in control of their own layout. */ .wrn-bg-page { background-color: var(--wrn-color-bg); } .wrn-bg-surface { background-color: var(--wrn-color-surface); } .wrn-bg-surface-2 { background-color: var(--wrn-color-surface-2); } .wrn-bg-primary { background-color: var(--wrn-color-primary); color: var(--wrn-color-primary-contrast); } .wrn-bg-secondary { background-color: var(--wrn-color-secondary); color: var(--wrn-color-secondary-contrast); } .wrn-text { color: var(--wrn-color-text); } .wrn-text-muted { color: var(--wrn-color-muted); } .wrn-text-primary { color: var(--wrn-color-primary); } .wrn-text-success { color: var(--wrn-color-success); } .wrn-text-warning { color: var(--wrn-color-warning); } .wrn-text-danger { color: var(--wrn-color-danger); } .wrn-border { border-color: var(--wrn-color-border); } [data-component] { animation: wrn-component-enter var(--wrn-motion-slow) var(--wrn-ease-emphasized) both; } [data-component] :where(button, a, input, select, textarea, summary, [role="button"], [role="tab"]) { transition-property: color, background-color, border-color, opacity, box-shadow, transform; transition-duration: var(--wrn-motion-base); transition-timing-function: var(--wrn-ease-standard); } [data-component] :where(input, select, textarea, .wrn-input, .wrn-select) { transition-duration: var(--wrn-motion-fast); } [data-component] :where(.wrn-panel, .wrn-surface, .wrn-catalog-card, article) { transition-property: border-color, background-color, box-shadow, transform; transition-duration: var(--wrn-motion-base); transition-timing-function: var(--wrn-ease-emphasized); } [data-component] :where(.wrn-overlay, [role="dialog"]) { animation: wrn-overlay-enter var(--wrn-motion-base) var(--wrn-ease-standard) both; } [data-component] :where(.wrn-dialog, [role="dialog"] > :first-child) { animation: wrn-dialog-enter var(--wrn-motion-slow) var(--wrn-ease-emphasized) both; } [data-component] :where([role="progressbar"], progress) { transition: inline-size var(--wrn-motion-slow) var(--wrn-ease-emphasized); } @media (hover: hover) and (pointer: fine) { [data-component] :where(button, [role="button"]):not(:disabled):hover { transform: translateY(-1px); } [data-component] :where(.wrn-catalog-card, article):has(a):hover { transform: translateY(-2px); box-shadow: 0 0.75rem 2rem rgb(15 23 42 / 0.12); } } [data-component] :where(button, [role="button"]):not(:disabled):active { transform: translateY(0) scale(0.98); transition-duration: var(--wrn-motion-fast); } @keyframes wrn-component-enter { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } } @keyframes wrn-overlay-enter { from { opacity: 0; } to { opacity: 1; } } @keyframes wrn-dialog-enter { from { opacity: 0; transform: translateY(12px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes wrn-popover-enter { from { opacity: 0; transform: translateY(-4px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } @media (prefers-reduced-motion: reduce) { [data-component], [data-component] *, [data-component] *::before, [data-component] *::after { scroll-behavior: auto !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0ms !important; } } @media (max-width: 480px) { .wrn-form-row { grid-template-columns: 1fr; } .wrn-filter-bar { align-items: stretch; flex-direction: column; } .wrn-filter-bar__controls { display: grid; } .wrn-dialog__actions > * { flex: 1 1 100%; } } /* --- Expanded foundation catalog ---------------------------------------- */ .wrn-container--narrow { max-width: 44rem; } .wrn-container--wide { max-width: 90rem; } .wrn-full-bleed { width: 100vw; margin-inline: calc(50% - 50vw); } .wrn-flex { display: flex; flex-wrap: wrap; gap: 1rem; min-width: 0; } .wrn-auto-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: 1rem; } .wrn-split-layout { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: center; gap: clamp(1.5rem, 5vw, 5rem); } .wrn-sticky-layout { position: sticky; top: 1rem; align-self: start; } .wrn-aspect-ratio { aspect-ratio: 16 / 9; overflow: hidden; } .wrn-panel, .wrn-surface, .wrn-well, .wrn-inset-panel { min-width: 0; padding: clamp(1rem, 3vw, 1.5rem); color: var(--wrn-color-text); border: 1px solid var(--wrn-color-border); border-radius: var(--wrn-radius); } .wrn-panel, .wrn-surface { background: var(--wrn-color-surface); box-shadow: var(--wrn-shadow-1); } .wrn-well, .wrn-inset-panel { background: var(--wrn-color-surface-2); box-shadow: inset 0 1px 2px rgb(0 0 0 / 0.06); } .wrn-scroll-area { max-width: 100%; overflow: auto; overscroll-behavior: contain; scrollbar-gutter: stable; } .wrn-sticky { position: sticky; top: 1rem; z-index: 10; } .wrn-muted { color: var(--wrn-color-muted); } .wrn-visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; } @media (max-width: 768px) { .wrn-split-layout, .wrn-sidebar-layout { grid-template-columns: 1fr; } .wrn-sticky-layout { position: static; } }