/* ──────────────────────────────────────────────────────────────────────────────
   games-mobile.css
   Universal iOS / touch / responsive base loaded by embed_layout.php for every
   embedded game (Cybersiege, Crimopolis, Island Life, Pica, Sector Wars,
   Stellar Drift). Per-game responsive overrides live inside each
   game's own view file and override these defaults where needed.
   ──────────────────────────────────────────────────────────────────────────── */

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    -webkit-tap-highlight-color: rgba(201, 168, 76, .18);
    overscroll-behavior-y: none;
}

/* iOS safe-area side padding for notched iPhones in landscape.
   Games that need full-bleed (e.g. Cybersiege topbar) override this. */
@supports (padding: max(0px)) {
    body {
        padding-left: env(safe-area-inset-left);
        padding-right: env(safe-area-inset-right);
    }
}

/* Smooth momentum scrolling on iOS for any scrollable container */
.scrollable, [data-scrollable] {
    -webkit-overflow-scrolling: touch;
}

/* ──────────────────────────────────────────────────────────────────────────────
   Touch / coarse-pointer rules
   These apply to ALL touch devices regardless of viewport — phones, tablets,
   touch-screen laptops. Mouse-only desktops are unaffected.
   ──────────────────────────────────────────────────────────────────────────── */
@media (pointer: coarse) {

    /* iOS auto-zooms inputs <16px on focus. Force minimum 16px. Per-game CSS
       can opt out for read-only/numeric inputs by raising specificity. */
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea {
        font-size: 16px !important;
    }

    /* Hover-only tooltips can't be triggered on touch — neutralise the common
       patterns used across the games. Per-game CSS may add more selectors. */
    [data-tip]:hover::after,
    [data-tip]:hover::before,
    .tip:hover::after,
    .tip:hover::before,
    .cs-tip:hover::after,
    .cs-tip:hover::before,
    .crim-tip:hover .crim-tip-pop,
    [title]:hover::after { /* harmless safety net */
        opacity: 0 !important;
        pointer-events: none !important;
    }

    /* Bigger minimum tap targets for common control patterns. Apple HIG = 44pt. */
    button,
    .btn,
    a.btn,
    [role="button"],
    input[type="button"],
    input[type="submit"],
    input[type="reset"] {
        min-height: 36px;
    }

    /* Tighter checkbox/radio hit-area without resizing the visual control */
    input[type="checkbox"],
    input[type="radio"] {
        min-width: 18px;
        min-height: 18px;
    }
}

/* Keyboard-aware: Bootstrap modals/inputs sometimes get the iOS keyboard
   pushed under fixed elements. Use visualViewport-friendly insets where
   possible. (No-op on non-iOS.) */
@supports (height: 100dvh) {
    .vh-100 { height: 100dvh !important; }
}

/* ──────────────────────────────────────────────────────────────────────────────
   Utility classes — promoted from the high-frequency inline-style patterns
   found by tools/inline_style_histogram.php. Use these instead of inline
   `style="color:#888"` etc., so views can carry a CSP that doesn't need
   'unsafe-inline'. CSS-variable references keep the values in one place.
   ──────────────────────────────────────────────────────────────────────────── */
/* Text colors — typographic hierarchy on the dark theme */
.pb-c-bright  { color: #e8e0d0 !important; }      /* primary copy */
.pb-c-dim     { color: #aaa     !important; }      /* secondary copy */
.pb-c-muted   { color: #888     !important; }      /* tertiary / hint */
.pb-c-faint   { color: #555     !important; }      /* lowest emphasis */
.pb-c-low     { color: #666     !important; }      /* between muted and faint */
.pb-c-gold    { color: #c9a84c !important; }      /* brand accent */
.pb-c-success { color: #6fdc9c !important; }      /* status: good */
.pb-c-warning { color: #ffe083 !important; }      /* status: caution */
.pb-c-danger  { color: #ff8d99 !important; }      /* status: bad */
.pb-c-info    { color: #8ab6ff !important; }      /* status: info */

/* Font-size scale — keeps the .72/.75/.78/.8/.85rem ladder named */
.pb-fs-xxs    { font-size: .72rem !important; }
.pb-fs-xs     { font-size: .75rem !important; }
.pb-fs-sm     { font-size: .8rem !important; }
.pb-fs-md     { font-size: .85rem !important; }
.pb-fs-lg     { font-size: .92rem !important; }

/* Text transform / family / misc */
.pb-uppercase  { text-transform: uppercase !important; letter-spacing: .5px; }
.pb-mono       { font-family: 'SF Mono', Consolas, Menlo, monospace !important; }
.pb-fw-700     { font-weight: 700 !important; }
.pb-fw-600     { font-weight: 600 !important; }

/* ──────────────────────────────────────────────────────────────────────────────
   Standardized status badges
   Single design-token set replacing the half-dozen inline `background:rgba(…)`
   badge variations scattered across admin pages. Use `.pb-badge .pb-badge-{kind}`
   anywhere a status pill is rendered.
   ──────────────────────────────────────────────────────────────────────────── */
.pb-badge {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .25em .65em;
    font-size: .75rem; font-weight: 600;
    border-radius: 999px;
    line-height: 1.35;
    white-space: nowrap;
    border: 1px solid transparent;
}
.pb-badge-success { background: rgba(25, 135, 84, .20); color: #6fdc9c; border-color: rgba(25, 135, 84, .30); }
.pb-badge-warning { background: rgba(255, 193, 7, .20); color: #ffe083; border-color: rgba(255, 193, 7, .30); }
.pb-badge-danger  { background: rgba(220, 53, 69, .20); color: #ff9aa6; border-color: rgba(220, 53, 69, .30); }
.pb-badge-info    { background: rgba(13, 110, 253, .20); color: #8ab6ff; border-color: rgba(13, 110, 253, .30); }
.pb-badge-muted   { background: rgba(108, 117, 125, .20); color: #adb5bd; border-color: rgba(108, 117, 125, .25); }
.pb-badge-admin   { background: rgba(201, 168, 76, .20); color: #c9a84c; border-color: rgba(201, 168, 76, .35); }
.pb-badge-vip     { background: linear-gradient(135deg, rgba(201,168,76,.25), rgba(201,168,76,.10)); color: #f0d080; border-color: rgba(201, 168, 76, .45); }
/* Status-named aliases for readability at the call site. */
.pb-badge-active   { background: rgba(25, 135, 84, .20); color: #6fdc9c; border-color: rgba(25, 135, 84, .30); }
.pb-badge-inactive { background: rgba(220, 53, 69, .20); color: #ff9aa6; border-color: rgba(220, 53, 69, .30); }
.pb-badge-pending  { background: rgba(255, 193, 7, .20); color: #ffe083; border-color: rgba(255, 193, 7, .30); }
.pb-badge-open     { background: rgba(13, 110, 253, .20); color: #8ab6ff; border-color: rgba(13, 110, 253, .30); }
.pb-badge-closed   { background: rgba(108, 117, 125, .20); color: #adb5bd; border-color: rgba(108, 117, 125, .25); }

/* ──────────────────────────────────────────────────────────────────────────────
   Required field marker
   Pair with <span class="required-mark">*</span> next to <label> text or use
   the [data-required] data-attribute on the input.
   ──────────────────────────────────────────────────────────────────────────── */
.required-mark,
.form-label[data-required]::after {
    color: #ff9aa6;
    font-weight: 700;
    margin-left: .25em;
}
.form-label[data-required]::after { content: '*'; }

/* ──────────────────────────────────────────────────────────────────────────────
   Form validation visual feedback
   `:user-invalid` (modern) / `:invalid:not(:focus)` (fallback) flag a
   field that the user has interacted with and that fails its constraint
   (required / type / pattern / minlength / etc.). This gives instant
   visual feedback without waiting for server-side validation to round-
   trip. Only fires AFTER first interaction so empty pristine fields
   don't all glow red on page load.
   ──────────────────────────────────────────────────────────────────────────── */
input:user-invalid:not(:focus),
select:user-invalid:not(:focus),
textarea:user-invalid:not(:focus) {
    border-color: rgba(220, 53, 69, 0.7) !important;
    box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.18) !important;
}
/* Older Safari / Firefox fallback — fires after blur thanks to :placeholder-shown trick */
@supports not selector(:user-invalid) {
    input:not(:focus):not(:placeholder-shown):invalid,
    select:not(:focus):invalid,
    textarea:not(:focus):not(:placeholder-shown):invalid {
        border-color: rgba(220, 53, 69, 0.7) !important;
        box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.18) !important;
    }
}
/* Valid state confirmation — subtle, only when a value is present. */
input:user-valid:not(:focus):not(:placeholder-shown),
select:user-valid:not(:focus),
textarea:user-valid:not(:focus):not(:placeholder-shown) {
    border-color: rgba(25, 135, 84, 0.45) !important;
}

/* ──────────────────────────────────────────────────────────────────────────────
   CLS guard
   Bootstrap's `img-fluid` (and ad-hoc inline `width:100%;height:auto`) strip
   the natural dimensions, so the browser can't reserve space until the image
   loads — every image swap cascades a layout shift down the rest of the
   page. The rule below tells the browser to use the image's intrinsic
   aspect ratio whenever an explicit dimension isn't set. It's a one-line
   bandage; per-call <img width="…" height="…"> attributes are still better.
   ──────────────────────────────────────────────────────────────────────── */
img:not([width]):not([height]):not([style*="width"]):not([style*="height"]) {
    height: auto;
    aspect-ratio: attr(width number) / attr(height number);
}

/* ──────────────────────────────────────────────────────────────────────────────
   Loading shimmer / skeleton placeholders
   Apply `.pb-skeleton` to a container that wraps placeholder content while it
   loads. The animation respects prefers-reduced-motion via the global
   layout-level rule. Colors track the gold/dark brand without depending on
   the layout's CSS variables, so this works inside game iframes too.
   ──────────────────────────────────────────────────────────────────────────── */
.pb-skeleton, .pb-skeleton-line, .pb-skeleton-block {
    position: relative;
    overflow: hidden;
    background: linear-gradient(90deg,
        rgba(201, 168, 76, 0.06) 0%,
        rgba(201, 168, 76, 0.14) 50%,
        rgba(201, 168, 76, 0.06) 100%);
    background-size: 200% 100%;
    animation: pb-shimmer 1.4s ease-in-out infinite;
    border-radius: 6px;
    color: transparent !important;
    user-select: none;
    pointer-events: none;
}
.pb-skeleton-line  { height: 0.85em; margin: .35em 0; }
.pb-skeleton-block { width: 100%; height: 120px; }
@keyframes pb-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ──────────────────────────────────────────────────────────────────────────────
   Print stylesheet
   The portal is mostly informational, but receipts (POS sales / payouts /
   credits) and case audit pages need to print clean. Strip nav/sidebar
   chrome and force black-on-white so the receipt is readable on cheap
   thermal/dot-matrix printers commonly used at the cashier counter.
   Wrap any printable receipt in `.pb-print-page` for clean page-breaks;
   add `.pb-no-print` to UI elements that should disappear (e.g. action
   buttons that don't apply on paper).
   ──────────────────────────────────────────────────────────────────────────── */
@media print {
    *, *::before, *::after { background: transparent !important; color: #000 !important; box-shadow: none !important; text-shadow: none !important; }
    body { background: #fff !important; }
    .navbar, .sidebar, .topbar, footer, .skip-link, .menu-toggle,
    .btn, .alert-dismissible .btn-close, .pb-no-print { display: none !important; }
    .main-content, main { margin: 0 !important; padding: 0 !important; }
    .pb-print-page { page-break-after: always; }
    .pb-print-page:last-child { page-break-after: auto; }
    table, th, td { border: 1px solid #999 !important; }
    th, td { padding: 4px 8px !important; }
    a:not([href^="#"])::after { content: " (" attr(href) ")"; font-size: 0.85em; color: #555 !important; }
    .pb-print-fit { max-width: 100% !important; width: auto !important; }
}
