T-HUB/apps/web/src/app/globals.css
glass beadian d9e8cdf789 feat: produce worker deployment + web producer/collective/branding UI + mobile CSS (wave-2c)
Deployment (t4g2): media-worker gains font-dejavu (drawtext lower-thirds)
and a dedicated produce-worker compose service running src/produce.ts —
claims video_processing_jobs compose|mix by lane, renders assembled/
overlaid/voiced cuts, registers derived library assets. Deliberately its
own process so a remote-lane box needs only Postgres + S3 + ffmpeg.

Web: compose media attachments UI (t2), Producer panel in the video
drawer (t5), collective creation + branding settings + shell branding
(brandweb), mobile CSS (mcss: touch targets, icon sizing, safe areas).
2026-10-14 20:40:49 +00:00

190 lines
6.4 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";
@theme {
--color-bg: oklch(0.11 0.008 25);
--color-surface: oklch(0.15 0.01 25);
--color-surface-2: oklch(0.19 0.012 25);
--color-border: oklch(0.26 0.02 25);
--color-border-subtle: oklch(0.22 0.015 25);
--color-text: oklch(0.93 0.005 25);
--color-text-dim: oklch(0.62 0.02 25);
--color-text-faint: oklch(0.46 0.02 25);
--color-accent: #ff1610;
--color-accent-hover: #e3130e;
--color-accent-dim: rgb(255 22 16 / 0.15);
--color-live: oklch(0.72 0.19 145);
--color-warn: oklch(0.78 0.16 85);
--color-danger: oklch(0.55 0.24 15);
--color-added: oklch(0.72 0.16 145);
--color-removed: oklch(0.55 0.24 15);
--font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-mono: ui-monospace, "SF Mono", Menlo, monospace;
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--text-2xs: 0.6875rem;
--text-xs: 0.75rem;
--text-sm: 0.8125rem;
--text-base: 0.875rem;
--text-lg: 1rem;
--mobile-tab-height: 76px;
--mobile-fab-size: 64px;
--mobile-sheet-radius: 28px;
--mobile-safe-bottom: env(safe-area-inset-bottom, 0px);
}
@theme inline {
--color-brand: var(--color-accent);
}
html {
color-scheme: dark;
}
body {
background: var(--color-bg);
color: var(--color-text);
font-family: var(--font-sans);
font-size: var(--text-base);
-webkit-font-smoothing: antialiased;
}
html, body { max-width: 100%; }
@media (max-width: 1023px) {
body { overflow-x: hidden; }
[data-mobile-main] :is(button, a[href], input, select, textarea, [role="tab"]) {
min-height: 44px;
}
[data-mobile-main] :is(button, a[href], [role="tab"]) {
min-width: 44px;
}
[data-mobile-main] p a[href] { display: inline-flex; align-items: center; }
[data-mobile-main] .mobile-stack-table,
[data-mobile-main] .mobile-stack-table tbody,
[data-mobile-main] .mobile-stack-table tr,
[data-mobile-main] .mobile-stack-table td { display: block; width: 100%; min-width: 0; }
[data-mobile-main] .mobile-stack-table thead { display: none; }
[data-mobile-main] .mobile-stack-table tr { padding: 8px 0; }
[data-mobile-main] .mobile-stack-table td { overflow-wrap: anywhere; }
[data-mobile-main] .mobile-stack-table td > * { max-width: 100%; }
}
/* ---------------------------------------------------------------------------
Phone tier (≤640px) — native feel, touch targets, safe areas, overflow.
Scoped globally (body-wide) rather than to [data-mobile-main] because the
auth screens (/login, /signup, /join, /submit, /oidc) and the body-portal
sheets render outside the main shell and were getting none of this.
These rules are unlayered, so they outrank Tailwind's `@layer utilities`
without needing !important.
--------------------------------------------------------------------------- */
@media (max-width: 640px) {
/* -- Native feel: no tap highlight flash, no double-tap-zoom delay on
controls (pinch zoom stays available — `manipulation` only disables
the double-tap gesture), no iOS landscape text inflation, no document
rubber-band behind the app shell. -- */
html {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
overscroll-behavior: none;
overflow-x: hidden;
}
body {
max-width: 100%;
overflow-x: hidden;
-webkit-tap-highlight-color: transparent;
}
body :where(button, a[href], [role="tab"], [role="button"], [role="switch"]) {
touch-action: manipulation;
}
/* -- ≥44px touch targets for buttons / icon-buttons (glyph buttons here are
plain <button>, bottom-nav tabs are <a>, segmented control is role=tab,
sheet drag handle is role=button). min-width is limited to controls that
are already box-shaped so inline text links keep their flow shape. -- */
body :where(button, a[href], [role="tab"], [role="button"], [role="switch"]) {
min-height: 44px;
}
body :where(nav button, nav a[href], [role="tab"]) {
min-width: 44px;
}
/* -- 16px minimum on text-entry controls: iOS Safari auto-zooms the viewport
on focus whenever the field's computed font-size is under 16px, which
reads as janky/non-native. Non-text inputs excluded (their size is
visual, not textual). -- */
body :where(
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="button"]):not([type="submit"]):not([type="reset"]),
select,
textarea
) {
font-size: 16px;
}
/* -- Icon sizing. Icons size via width/height attributes from React props,
not a CSS variable or utility class — but HTML sizing attributes are
presentational hints, so author CSS still wins without touching TSX.
Bottom-nav glyph: 24px → 22px (target band 20–22px; top of band keeps
it clearest at phone density). Inline SVG icons: ≥16px floor so the
14px spinners and 11px arrow glyphs stop rendering sub-legibly. -- */
nav[aria-label="Primary navigation"] img {
width: 22px;
height: 22px;
}
body :where(svg) {
min-width: 16px;
min-height: 16px;
}
/* -- Safe areas. Bottom is already covered app-wide via --mobile-safe-bottom
(bottom nav, sheets, compose's fixed action bar). This adds the other
three edges on the shell column that holds top bar + main + bottom nav
— the notch/home-indicator sides that only bite in landscape.
max() keeps the value at 0 on devices without insets, and degrades to
no padding at all on browsers without :has(). -- */
:has(> main[data-mobile-main]) {
padding-top: max(0px, env(safe-area-inset-top, 0px));
padding-left: max(0px, env(safe-area-inset-left, 0px));
padding-right: max(0px, env(safe-area-inset-right, 0px));
}
/* -- Horizontal overflow guards: belt-and-braces on the scroller plus a
cap on replaced media, the classic cause of stray phone scroll. -- */
main[data-mobile-main] {
max-width: 100%;
}
body :where(img, video, canvas, iframe, svg) {
max-width: 100%;
}
}
::selection {
background: var(--color-accent-dim);
}
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 1px;
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background: var(--color-border);
border-radius: 3px;
}