@import 'tailwindcss';
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@fontsource-variable/geist";
@import "./colorThemes.css";

@custom-variant dark (&:is(.dark *));
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/typography';

@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php';
@source '../**/*.blade.php';
@source '../**/*.{js,ts,jsx,tsx}';

@theme {
    --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
        'Segoe UI Symbol', 'Noto Color Emoji';

    /* Extend Tailwind's breakpoint scale past 2xl. Adds the `3xl:` modifier
     * and lets `.container` widen to 1920px on ultra-wide monitors so the
     * y8-style category strips can show their full 10-tile slide instead
     * of getting clipped to the 2xl (1536px) cap. */
    --breakpoint-3xl: 1920px;
}

@theme inline {
    --font-heading: var(--font-sans);
    --font-sans: 'Geist Variable', sans-serif;
    --color-sidebar-ring: var(--sidebar-ring);
    --color-sidebar-border: var(--sidebar-border);
    --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
    --color-sidebar-accent: var(--sidebar-accent);
    --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
    --color-sidebar-primary: var(--sidebar-primary);
    --color-sidebar-foreground: var(--sidebar-foreground);
    --color-sidebar: var(--sidebar);
    --color-chart-5: var(--chart-5);
    --color-chart-4: var(--chart-4);
    --color-chart-3: var(--chart-3);
    --color-chart-2: var(--chart-2);
    --color-chart-1: var(--chart-1);
    --color-ring: var(--ring);
    --color-input: var(--input);
    --color-border: var(--border);
    --color-destructive: var(--destructive);
    --color-accent-foreground: var(--accent-foreground);
    --color-accent: var(--accent);
    --color-muted-foreground: var(--muted-foreground);
    --color-muted: var(--muted);
    --color-secondary-foreground: var(--secondary-foreground);
    --color-secondary: var(--secondary);
    --color-primary-foreground: var(--primary-foreground);
    --color-primary: var(--primary);
    --color-popover-foreground: var(--popover-foreground);
    --color-popover: var(--popover);
    --color-card-foreground: var(--card-foreground);
    --color-card: var(--card);
    --color-foreground: var(--foreground);
    --color-background: var(--background);
    --radius-sm: calc(var(--radius) * 0.6);
    --radius-md: calc(var(--radius) * 0.8);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) * 1.4);
    --radius-2xl: calc(var(--radius) * 1.8);
    --radius-3xl: calc(var(--radius) * 2.2);
    --radius-4xl: calc(var(--radius) * 2.6);
}

:root {
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.145 0 0);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.145 0 0);
    --primary: oklch(0.205 0 0);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
    --muted: oklch(0.97 0 0);
    --muted-foreground: oklch(0.556 0 0);
    --accent: oklch(0.97 0 0);
    --accent-foreground: oklch(0.205 0 0);
    --destructive: oklch(0.577 0.245 27.325);
    --border: oklch(0.922 0 0);
    --input: oklch(0.922 0 0);
    --ring: oklch(0.708 0 0);
    --chart-1: oklch(0.87 0 0);
    --chart-2: oklch(0.556 0 0);
    --chart-3: oklch(0.439 0 0);
    --chart-4: oklch(0.371 0 0);
    --chart-5: oklch(0.269 0 0);
    --radius: 0.625rem;
    --sidebar: oklch(0.985 0 0);
    --sidebar-foreground: oklch(0.145 0 0);
    --sidebar-primary: oklch(0.205 0 0);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.97 0 0);
    --sidebar-accent-foreground: oklch(0.205 0 0);
    --sidebar-border: oklch(0.922 0 0);
    --sidebar-ring: oklch(0.708 0 0);
}

.dark {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --popover: oklch(0.205 0 0);
    --popover-foreground: oklch(0.985 0 0);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.269 0 0);
    --muted-foreground: oklch(0.708 0 0);
    --accent: oklch(0.269 0 0);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.556 0 0);
    --chart-1: oklch(0.87 0 0);
    --chart-2: oklch(0.556 0 0);
    --chart-3: oklch(0.439 0 0);
    --chart-4: oklch(0.371 0 0);
    --chart-5: oklch(0.269 0 0);
    --sidebar: oklch(0.205 0 0);
    --sidebar-foreground: oklch(0.985 0 0);
    --sidebar-primary: oklch(0.488 0.243 264.376);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.269 0 0);
    --sidebar-accent-foreground: oklch(0.985 0 0);
    --sidebar-border: oklch(1 0 0 / 10%);
    --sidebar-ring: oklch(0.556 0 0);
}

@layer base {
  * {
    @apply border-border outline-ring/50;
    }
  body {
    @apply bg-background text-foreground;
    }
  html {
    @apply font-sans;
    }
}

/*
 * Themed scrollbar for admin surfaces (modals, sidebars, long pages).
 * Opt-in via `className="admin-scroll"` so we don't touch native OS scrollbar
 * behaviour everywhere. Firefox uses scrollbar-color (no pseudo-element),
 * Webkit/Blink uses ::-webkit-scrollbar. Both pull the shadcn --muted and
 * --border tokens so dark + light modes inherit correctly, and the thumb
 * stays 8px thin to match Radix ScrollArea's visual weight.
 */
.admin-scroll {
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

.admin-scroll::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

.admin-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.admin-scroll::-webkit-scrollbar-thumb {
    background-color: var(--border);
    border-radius: 9999px;
    border: 2px solid transparent;
    background-clip: padding-box;
}

.admin-scroll:hover::-webkit-scrollbar-thumb,
.admin-scroll::-webkit-scrollbar-thumb:hover {
    background-color: var(--muted-foreground);
    background-clip: padding-box;
}

.admin-scroll::-webkit-scrollbar-corner {
    background: transparent;
}

/*
 * Scrollbar-free utility for 10-foot UIs (Arcade TV grid rows + outer
 * container). The TV surface is operated by d-pad/remote, never a mouse,
 * so visible scrollbars are noise — they also visually compete with the
 * card focus ring. Cross-browser:
 *   - Webkit/Blink: ::-webkit-scrollbar { display: none }
 *   - Firefox: scrollbar-width: none
 *   - Legacy IE/Edge: -ms-overflow-style: none
 * Scrolling itself stays fully functional.
 */
.scrollbar-hide {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.scrollbar-hide::-webkit-scrollbar {
    display: none;
}

/*
 * iOS Safari auto-zooms when an input/textarea/select with font-size <16px
 * receives focus — and silently REFUSES to zoom back out, leaving the page
 * stuck zoomed in after navigation (the Login → Remote flow lands users on
 * the Arcade TV controller with the layout permanently zoomed past the
 * viewport edge). Forcing ≥16px on touch devices (Safari's heuristic for
 * "real iOS keyboard") sidesteps the zoom entirely.
 *
 * `(hover: none) and (pointer: coarse)` targets touchscreens specifically,
 * so desktop layouts that intentionally use 14px (text-sm) inputs aren't
 * affected. `max(16px, 1em)` preserves any larger explicit size set by a
 * component override (e.g. text-lg on a hero search bar stays bigger).
 *
 * Defense-in-depth — every input-heavy page should ideally specify
 * text-base on mobile already (e.g. shadcn Input's `text-base md:text-sm`
 * default), but this rule guarantees the property even when a page
 * override drops the font-size below 16px.
 */
@media (hover: none) and (pointer: coarse) {
    input:not([type='checkbox']):not([type='radio']):not([type='range']),
    select,
    textarea {
        font-size: max(16px, 1em);
    }
}

/*
 * TipTap placeholder rendering. The extension tags the first empty node with
 * .is-editor-empty + data-placeholder="…" but doesn't draw the hint itself —
 * this rule does. Kept global so every TipTap mount inherits the same look.
 */
.ProseMirror p.is-editor-empty:first-child::before,
.ProseMirror h1.is-editor-empty:first-child::before,
.ProseMirror h2.is-editor-empty:first-child::before,
.ProseMirror h3.is-editor-empty:first-child::before {
    content: attr(data-placeholder);
    color: var(--muted-foreground);
    float: left;
    height: 0;
    pointer-events: none;
}

/*
 * Tournament Hall of Fame animations.
 */
@keyframes hof-fade-up {
    from { opacity: 0; transform: translateY(16px); }
    to { opacity: 1; transform: translateY(0); }
}
@keyframes hof-trophy-glow {
    0%, 100% { filter: drop-shadow(0 0 4px rgba(245,158,11,0.4)); }
    50% { filter: drop-shadow(0 0 12px rgba(245,158,11,0.7)); }
}
@keyframes hof-scale-in {
    from { opacity: 0; transform: scale(0.85); }
    to { opacity: 1; transform: scale(1); }
}
@keyframes hof-shimmer {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(100%); }
}
@keyframes hof-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
}
.hof-entry { animation: hof-fade-up 0.5s ease-out both; }
.hof-champion { animation: hof-scale-in 0.55s ease-out both; }

/*
 * Cover-frame animations — used by FrameWrapper.tsx via animate-cosmetic-*.
 * Respect prefers-reduced-motion: animations disable for users who opt out.
 */
@keyframes cosmetic-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.55; }
}
@keyframes cosmetic-breathe {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.04); }
}
@keyframes cosmetic-shimmer {
    0% { transform: translateX(-150%); }
    100% { transform: translateX(150%); }
}
@keyframes cosmetic-glow {
    0%, 100% { box-shadow: 0 0 var(--cosmetic-glow-size, 12px) var(--cosmetic-glow-color, currentColor); }
    50% { box-shadow: 0 0 calc(var(--cosmetic-glow-size, 12px) * 1.6) var(--cosmetic-glow-color, currentColor); }
}
.animate-cosmetic-pulse { animation: cosmetic-pulse 2.4s ease-in-out infinite; }
.animate-cosmetic-breathe { animation: cosmetic-breathe 3s ease-in-out infinite; }
.animate-cosmetic-glow { animation: cosmetic-glow 2.4s ease-in-out infinite; }
/* Shimmer adds an animated diagonal light sweep across the frame's wrapped
   content via an absolutely-positioned ::after overlay. Parent must be
   position:relative + overflow:hidden — both are already true on every
   FrameWrapper code path. */
.animate-cosmetic-shimmer { position: relative; overflow: hidden; }
.animate-cosmetic-shimmer::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, 0.45) 50%, transparent 65%);
    animation: cosmetic-shimmer 2.6s ease-in-out infinite;
    pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
    .animate-cosmetic-pulse,
    .animate-cosmetic-breathe,
    .animate-cosmetic-glow,
    .animate-cosmetic-shimmer::after { animation: none; }
}

/*
 * Arcade TV banner marquee — drives the home-page hero collage. The track
 * contains the games twice and translates from 0 to -50%, so the second
 * set lands exactly where the first set started for a seamless loop.
 */
@keyframes arcade-tv-marquee {
    from { transform: translate3d(0, 0, 0); }
    to { transform: translate3d(-50%, 0, 0); }
}
.animate-arcade-tv-marquee { animation: arcade-tv-marquee 32s linear infinite; }
.animate-arcade-tv-marquee:hover { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
    .animate-arcade-tv-marquee { animation: none; }
}
