/* ───────────────────────── UI/UX POLISH ─────────────────────────────────── */

/* Tab bar labels — bump from ~10px to 12px, bold so they're actually readable */
nav [role="tab"],
nav button,
[class*="tab"] [class*="label"],
[class*="TabBar"] span,
[class*="tabbar"] span {
  font-size: 12px !important;
  font-weight: 700 !important;
  letter-spacing: .2px !important;
  color: #c9c5df !important;
  opacity: 1 !important;
}

/* Inactive tab icons/labels need enough contrast to read on pure black */
nav[role="tablist"] [role="tab"]:not([aria-selected="true"]) *,
[class*="TabBar"] [aria-selected="false"] *,
[class*="tabbar"] [aria-selected="false"] * {
  color: #b5b0d0 !important;
  opacity: 1 !important;
}

nav[role="tablist"] [role="tab"][aria-selected="true"] *,
[class*="TabBar"] [aria-selected="true"] *,
[class*="tabbar"] [aria-selected="true"] * {
  color: #ffb347 !important;
  opacity: 1 !important;
}

/* React Native Web bundle renders tab labels as <div class="css-146c3p1">
   with inline style font-size:9px; color:#3a2a5a; — boost both via !important.
   ONLY target the tiny 9px tab-bar labels so we don't clobber 32px score numbers. */
div.css-146c3p1[style*="font-size: 9px"],
div.css-146c3p1[style*="font-size:9px"] {
  font-size: 12px !important;
  font-weight: 700 !important;
  letter-spacing: .2px !important;
}
/* 10px label bump to 12px so small card captions stay readable */
div.css-146c3p1[style*="font-size: 10px"],
div.css-146c3p1[style*="font-size:10px"] {
  font-size: 12px !important;
}
/* Inactive labels (purple-on-black fail) — swap to a readable cool-grey */
div.css-146c3p1[style*="rgb(58, 42, 90)"],
div.css-146c3p1[style*="#3a2a5a"],
div.css-146c3p1[style*="rgb(107, 107, 138)"],
div.css-146c3p1[style*="rgb(122, 106, 154)"] {
  color: #c9c5df !important;
}

/* ── Result page: bigger score numbers + hide Face Shape row ──────────── */
/* Score numbers (overall/potential/jawline/...) render with inline
   "font-size: 32px; font-weight: 900;" — bump for impact. */
div.css-146c3p1[style*="font-size: 32px"],
div.css-146c3p1[style*="font-size:32px"] {
  font-size: 40px !important;
  line-height: 1.05 !important;
  letter-spacing: -0.5px !important;
}
/* Bump potential/actions-area numbers (the small tiles) */
div.css-146c3p1[style*="font-size: 20px"],
div.css-146c3p1[style*="font-size:20px"] {
  font-size: 26px !important;
}

/* Widen metric cards so the now-bigger numbers don't crowd the label.
   Force equal 50% width (minus half the 10px gap) so both cards in a row
   sit flush side-by-side and match the reference mockup. */
[style*="width: 142px"][style*="border-radius: 18px"] {
  width: calc(50% - 5px) !important;
  max-width: none !important;
  flex: 1 1 calc(50% - 5px) !important;
  box-sizing: border-box !important;
}

/* Desktop responsive — make the app fill the viewport up to a max width
   instead of leaving huge black margins either side. */
@media (min-width: 768px) {
  html, body, #root {
    min-height: 100vh;
  }
  #root > * {
    max-width: 560px !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
}

/* Lazy-load hint for images that the bundle doesn't specify loading= on.
   Browsers ignore `content-visibility` on already-loaded images, so it only
   helps for those still below the fold. */
img:not([loading]) {
  content-visibility: auto;
  contain-intrinsic-size: 64px 64px;
}

/* Contrast bump — darken extremely low-contrast grey text used for hints */
[style*="color:#333"],
[style*="color: #333"],
[style*="color:#444"],
[style*="color: #444"],
[style*="color:#555"],
[style*="color: #555"] {
  color: #9aa0b4 !important;
}

/* ── Performance: kill the always-on aurora/orb animations that overheat
      low-end devices. The doodee bundle drives `.orb-drift` + `.orb-drift-rev`
      around the screen edges with heavy `filter: blur(...)` GPU layers. */
.orb-drift,
.orb-drift-rev,
[class*="orb-drift"] {
  animation: none !important;
  filter: none !important;
  opacity: 0 !important;
  display: none !important;
}

/* Force a pure dark background behind the app — kills the purple/violet
   aurora bleeding past the centered mobile column on desktop viewports. */
html, body {
  background: #000000 !important;
  background-image: none !important;
  background-color: #000000 !important;
}
body::before, body::after {
  content: none !important;
  display: none !important;
  background: none !important;
  filter: none !important;
  animation: none !important;
}

/* Catch-all: any element using a heavy blur filter for ambient glow */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────────
   doodee a11y / interaction baseline
   Loaded first in every HTML <head>. Overrides page-level CSS vars + adds
   consistent focus rings and button states across admin / scan / money-maxxing.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── 1. WCAG-AA muted text contrast ────────────────────────────────────────
   Old tokens against dark bg:
     #6b6b8a ≈ 3.6:1 (fail)
     #7a6a9a ≈ 3.8:1 (fail)
     #3a2a5a ≈ 1.9:1 (fail)
   New tokens (≥ 4.5:1 against #08070f):
     --muted: #a8a6c4 ≈ 7.0:1
     --text2: #b0a8c8 ≈ 7.3:1
     --text3: #8a7fb0 ≈ 4.8:1 (borderline for large text only; we keep it for dividers)
*/
:root {
  --muted: #a8a6c4 !important;
  --text2: #b0a8c8 !important;
  --text3: #8a7fb0 !important;
}

/* Catch any hard-coded small-label colors in inline styles we can't easily edit. */
[style*="color:#6b6b8a"],
[style*="color: #6b6b8a"],
[style*="rgb(107, 107, 138)"] { color: #a8a6c4 !important; }
[style*="color:#7a6a9a"],
[style*="color: #7a6a9a"],
[style*="rgb(122, 106, 154)"] { color: #b0a8c8 !important; }
[style*="color:#3a2a5a"],
[style*="color: #3a2a5a"],
[style*="rgb(58, 42, 90)"] { color: #9590b8 !important; }

/* ── 2. Focus-visible ring — keyboard users only ──────────────────────────
   Replaces the bare `outline:none` seen across inputs/buttons. Using
   :focus-visible means mouse clicks don't show the ring, only keyboard
   tabbing or programmatic focus does.
*/
:where(button, a, input, select, textarea, [role="button"], [tabindex]):focus {
  outline: none;
}
:where(button, a, input, select, textarea, [role="button"], [tabindex]):focus-visible {
  outline: 2px solid #c4b5fd;
  outline-offset: 2px;
  border-radius: 6px;
  box-shadow: 0 0 0 4px rgba(167, 139, 250, 0.25);
}

/* Dark-on-light inputs get a higher-contrast ring */
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid #a78bfa;
  outline-offset: 0;
}

/* ── 3. Standardize button interaction states ─────────────────────────────
   Applied with low specificity via :where() so individual pages can still
   customize without fighting !important.
*/
:where(button, [role="button"], .btn) {
  transition: transform .12s ease, filter .12s ease, box-shadow .12s ease, background-color .12s ease;
  cursor: pointer;
}
:where(button, [role="button"], .btn):hover:not(:disabled):not([aria-disabled="true"]) {
  filter: brightness(1.08);
}
:where(button, [role="button"], .btn):active:not(:disabled):not([aria-disabled="true"]) {
  transform: scale(0.97);
}
:where(button, [role="button"], .btn):disabled,
:where(button, [role="button"], .btn)[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  filter: grayscale(0.25);
}

/* ── 4. Clickable divs that aren't proper buttons — make sure keyboard
      users see they're interactive. Apply to divs with onclick only. */
div[onclick],
div[role="button"]:not(button) {
  cursor: pointer;
}
div[onclick]:focus-visible,
div[role="button"]:focus-visible {
  outline: 2px solid #c4b5fd;
  outline-offset: 2px;
}

/* ── 5. Respect reduced-motion preferences ─────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  :where(button, [role="button"], .btn, a) {
    transition: none !important;
  }
  :where(*, *::before, *::after) {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── 6. Touch target size (mobile) — at least 40×40 for tappables ──────── */
@media (hover: none) and (pointer: coarse) {
  :where(button, a.btn, [role="button"]) {
    min-height: 40px;
    min-width: 40px;
  }
}

/* ── 7. Skip-to-content link (injected via JS in each page) ────────────── */
.skip-link {
  position: absolute;
  left: 8px;
  top: -40px;
  z-index: 9999;
  padding: 8px 14px;
  background: #a78bfa;
  color: #ffffff;
  font-weight: 700;
  border-radius: 8px;
  text-decoration: none;
  transition: top 0.2s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 8px;
}

/* ── 8. Tab bar polish — extra spacing + safe-area for iPhone notch ─────── */
nav[role="tablist"],
[class*="tabbar"],
[class*="TabBar"] {
  padding-bottom: max(env(safe-area-inset-bottom), 6px) !important;
}

/* ── 9. Smoother card hovers across the app ───────────────────────────── */
[class*="card"]:not([class*="discard"]):not([class*="picker"]) {
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

/* ── 10. Loading skeletons — gentle shimmer instead of jarring flashes ── */
@keyframes dd-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.dd-skeleton,
[class*="skeleton" i]:not(input):not(button) {
  background: linear-gradient(90deg, rgba(255,255,255,.04) 0%, rgba(167,139,250,.10) 50%, rgba(255,255,255,.04) 100%);
  background-size: 200% 100%;
  animation: dd-shimmer 1.6s linear infinite;
  border-radius: 8px;
}

/* ── 11. Selection color matches brand ──────────────────────────────── */
::selection { background: rgba(167,139,250,.35); color: #ffffff; }

/* ── 12. Scrollbar — thin, branded, optional ────────────────────────── */
* {
  scrollbar-width: thin;
  scrollbar-color: rgba(167,139,250,.3) transparent;
}
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: rgba(167,139,250,.3);
  border-radius: 3px;
}
*::-webkit-scrollbar-thumb:hover { background: rgba(167,139,250,.5); }

/* ── 13. Image loading state — soft placeholder, not jarring ─────────── */
img:not([src]),
img[src=""],
img[src*="data:image/gif;base64,R0lGOD"] {
  background: linear-gradient(135deg, rgba(167,139,250,.08), rgba(124,58,237,.04));
}

/* ── 14. Form validation states ──────────────────────────────────────── */
input:invalid:not(:placeholder-shown),
textarea:invalid:not(:placeholder-shown) {
  border-color: rgba(248,113,113,.6) !important;
  box-shadow: 0 0 0 2px rgba(248,113,113,.15) !important;
}
input:valid:not(:placeholder-shown),
textarea:valid:not(:placeholder-shown) {
  border-color: rgba(74,222,128,.4) !important;
}

/* ── 15. Onboarding/Reminders overlays — let them sit above everything ─ */
#dd-onboarding, #dd-rem-prompt {
  font-feature-settings: "ss01" on, "ss02" on;
}

/* ── 16. Minimum font size — prevent unreadable tiny text ──────────── */
/* Any element with computed < 12px gets bumped. Targets common culprits. */
[style*="font-size: 10px"], [style*="font-size:10px"],
[style*="font-size: 11px"], [style*="font-size:11px"],
[style*="fontSize: 10"], [style*="fontSize:10"],
[style*="fontSize: 11"], [style*="fontSize:11"] {
  font-size: 12px !important;
  line-height: 1.5 !important;
}

/* ── 17. Testimonial rotator animation ──────────────────────────────── */
#dd-testimonial-rotator { transition: opacity .4s ease; }
#dd-testimonial-rotator[data-fading="1"] { opacity: 0; }

/* ── 18. PWA install banner ─────────────────────────────────────────── */
#dd-pwa-install {
  position: fixed; bottom: 84px; left: 12px; right: 12px;
  max-width: 420px; margin: 0 auto;
  background: linear-gradient(145deg, #1a1730, #13102a);
  border: 1px solid rgba(167,139,250,.3);
  border-radius: 14px; padding: 12px 14px;
  color: #fff;
  display: flex; align-items: center; gap: 10px;
  box-shadow: 0 12px 30px rgba(0,0,0,.45);
  font: 700 13px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  z-index: 2147481000;
  animation: dd-pwa-slide .35s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes dd-pwa-slide { from{opacity:0;transform:translateY(14px);} to{opacity:1;transform:translateY(0);} }
#dd-pwa-install .dd-pwa-emoji { font-size: 22px; }
#dd-pwa-install .dd-pwa-text { flex: 1; }
#dd-pwa-install button {
  font: inherit; border: none; cursor: pointer; padding: 8px 14px;
  border-radius: 8px; font-weight: 700;
  transition: filter .12s ease;
}
#dd-pwa-install .dd-pwa-yes { background: linear-gradient(135deg,#a78bfa,#7c3aed); color:#fff; }
#dd-pwa-install .dd-pwa-no  { background: transparent; color: #a8a6c4; }
#dd-pwa-install button:hover { filter: brightness(1.1); }

/* ── Share button — big orange pill matching Continue-button reference ── */
[data-dd-share-btn="1"] {
  background: linear-gradient(135deg, #ff8a3d, #ea5a1a) !important;
  background-color: #ea5a1a !important;
  border-radius: 999px !important;
  padding: 16px 28px !important;
  min-height: 56px !important;
  width: calc(100% - 32px) !important;
  max-width: 480px !important;
  margin: 14px auto !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  box-shadow: 0 8px 24px rgba(234,90,26,.35), 0 2px 6px rgba(0,0,0,.3) !important;
  border: none !important;
  cursor: pointer !important;
  transition: transform .12s ease, filter .12s ease !important;
}
[data-dd-share-btn="1"]:hover {
  filter: brightness(1.06) !important;
}
[data-dd-share-btn="1"]:active {
  transform: scale(0.97) !important;
}
[data-dd-share-btn="1"] * {
  color: #ffffff !important;
  font-weight: 800 !important;
  font-size: 17px !important;
  letter-spacing: .3px !important;
  text-shadow: 0 1px 2px rgba(0,0,0,.15) !important;
}

/* ── 19. Lang toggle pill ───────────────────────────────────────────── */
#dd-lang-toggle {
  position: fixed; top: calc(env(safe-area-inset-top) + 10px); right: 10px;
  z-index: 2147480000;
  background: rgba(24,20,40,.92);
  border: 1px solid rgba(167,139,250,.3);
  border-radius: 999px;
  padding: 4px;
  display: flex; gap: 2px;
  font: 700 11px/-apple-system,sans-serif;
}
#dd-lang-toggle button {
  font: inherit; border: none; cursor: pointer; padding: 5px 10px;
  border-radius: 999px; background: transparent; color: #a8a6c4;
  transition: all .15s ease;
}
#dd-lang-toggle button.active {
  background: linear-gradient(135deg,#a78bfa,#7c3aed);
  color: #ffffff;
  box-shadow: 0 2px 8px rgba(124,58,237,.3);
}

/* ═══════════════════════════════════════════════════════════════════════════
   PERFORMANCE OVERRIDES (2026-04-21) — must come LAST so they win specificity.
   Mobile devices were overheating from heavy GPU compositing. Audit found:
     1. backdrop-filter blur(8–22px) on dozens of cards = #1 GPU killer
     2. body::before / aurora ::before with filter:blur(40–60px) + animation
        = continuous full-screen blur recompute every frame
     3. Animated box-shadow keyframes = repaint on every frame
     4. background-attachment:fixed + radial gradients = full-screen repaint
        on every scroll
     5. filter:drop-shadow on small SVG/border tricks = small but adds up
     6. Multiple stacked translucent layers each with own blur

   Fix philosophy: keep visual hierarchy (borders, gradients, modest shadows)
   but eliminate the GPU-heaviest tricks. Replace blurred backdrops with
   semi-opaque dark backgrounds so cards still "pop" without blur cost.
   ═══════════════════════════════════════════════════════════════════════════ */

/* (1) Kill ALL backdrop-filter site-wide. Single biggest win on mobile. */
*, *::before, *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* (2) Kill blur filter on every visible decorative element. We allow it on
       images (object-fit blur effects are rare and intentional). */
:not(img):not(video) {
  /* Don't touch elements that legitimately use filter for greyscale/etc. */
}
.scan-corners, .scan-corners *,
.scan-overlay-ring, .scan-scanline,
[class*="orb-"], [class*="aurora"],
body::before, body::after, html::before, html::after {
  filter: none !important;
  -webkit-filter: none !important;
}

/* (3) Hide the scan-overlay decorations entirely (animated rings + scanline +
       drop-shadow corners). They were animating constantly and used filter:blur
       AND drop-shadow — both expensive. Scan UX still works fine without them. */
.scan-overlay-ring, .scan-scanline, .scan-corners {
  display: none !important;
}

/* (4) Force scroll-attached background everywhere. `fixed` triggers a
       full-viewport repaint on every scroll frame on mobile WebKit. */
html, body, #root, [class*="background"], [class*="bg-"] {
  background-attachment: scroll !important;
}

/* (5) Override known animated keyframes that animate expensive properties.
       We keep the @keyframes name so JS / CSS that references them doesn't
       break — we just make the animation a no-op. */
@keyframes doodee-aurora { from, to { transform: none; opacity: .85; } }
@keyframes aurora        { from, to { transform: none; opacity: .85; } }
@keyframes pulse         { 0%, 100% { opacity: 1; } 50% { opacity: .6; } }
@keyframes pulse-glow    { 0%, 100% { opacity: 1; } 50% { opacity: .7; } }
@keyframes scan-spin     { from, to { transform: translate(-50%,-50%); } }
@keyframes scan-sweep    { from, to { top: 50%; opacity: 0; } }

/* (6) Cap heavy box-shadows on known offenders. Stripe/Money-Maxxing/Exercise
       cards used 30–80px blur radii — drop to a flat 8px shadow that still
       reads as "card lifted off background" without the GPU cost. */
.dd-stripe-btn,
.dd-stripe-embedded-wrap,
.dd-pay-btn,
#mm-profile-item,
.stat-card,
.exer-card,
.rank-overall,
.glow-circle,
.cd-circle,
.timer-pill,
.score-pill,
.status-pill,
.mode-btn,
[class*="glass"],
[class*="-card"]:not([class*="discard"]):not([class*="picker"]) {
  box-shadow: 0 4px 12px rgba(0,0,0,.35) !important;
}

/* (7) Kill the heavy "ambient glow" radial-gradient ::before pseudos that some
       cards use for the rank/exercise color halo. Pure decoration, scroll cost. */
.rank-overall::before,
.exer-card::before,
[class*="aurora"]::before,
[class*="aurora"]::after {
  display: none !important;
  content: none !important;
}

/* (8) Replace heavy glass-blur backgrounds with solid semi-opaque dark.
       Targets the common Expo View backgrounds that index.html previously
       boosted via backdrop-filter. Cards stay readable, no GPU cost. */
[style*="background-color: rgb(16, 16, 26)"],
[style*="background-color: rgb(26, 26, 40)"],
[style*="background-color: rgb(18, 18, 28)"],
[style*="background-color: rgb(14, 12, 30)"],
[style*="background-color:#10101a"],
[style*="background-color:#1a1a28"],
[style*="backgroundColor: rgb(16, 16, 26)"] {
  background: #14122a !important;
  border: 1px solid rgba(255,255,255,.08) !important;
  box-shadow: 0 4px 10px rgba(0,0,0,.30) !important;
}

/* (9) Disable will-change globally. Heavy bundles often set
       `will-change: transform` on hundreds of nodes which wastes GPU memory. */
* { will-change: auto !important; }

/* (10) Disable layout-thrashing transitions on unknown elements. Card hover
        transitions are still allowed (defined explicitly above). */
[class*="orb"], [class*="aurora"], [class*="floating"] {
  animation: none !important;
  transition: none !important;
  transform: none !important;
}

/* (11) Exercise page (camera HUD) — known heavy offenders not in the
        general selector list. These render OVER the live camera frame so
        every stale GPU layer is visible & every animation re-composites the
        whole video frame. Cap the box-shadows + text-shadows hard. */
.rep-counter, .rest-box, .challenge-timer,
.cam-header, .header, .header h1,
.streak-badge, .session-timer, .session-cal,
.tutorial-box, .cam-setup, .tut-anim, .tut-tips {
  box-shadow: 0 2px 6px rgba(0,0,0,.35) !important;
}
.countdown-num, .countdown-go, .rest-num, .rep-num,
.rank-name, .header h1, .cam-title, .tp-title {
  text-shadow: 0 0 6px currentColor !important;
}
.rank-icon svg, .tut-icon, .ec-count, [class*="-icon"] svg {
  filter: none !important;
}
/* The exercise pulse-glow that animated box-shadow on every frame —
   replace with cheap opacity blink. */
.challenge-timer.urgent { animation: dd-cheap-pulse .8s ease-in-out infinite alternate !important; }
@keyframes dd-cheap-pulse { from { opacity: 1; } to { opacity: .55; } }

/* (12) Replace exercise.html body radial-gradients with solid color. */
body { background-image: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════
   iOS PWA SAFE-AREA FIX (2026-04-21)
   ─── Why ────────────────────────────────────────────────────────────────
   index.html sets `apple-mobile-web-app-status-bar-style=black-translucent`
   + `viewport-fit=cover`. In PWA standalone mode (Add to Home Screen),
   iOS removes the URL bar AND makes the status bar a transparent overlay
   on top of page content. Without padding, the React-rendered "doodee"
   header overlaps the iOS clock/battery/signal icons.
   ─── Fix ────────────────────────────────────────────────────────────────
   Push #root down by `env(safe-area-inset-top)` ONLY when the page is
   running in standalone mode (PWA installed). In regular Safari/Chrome,
   the browser chrome already separates the status bar from the page, so
   no padding needed — `@media (display-mode: standalone)` gates this.
   On Android PWA, `env(safe-area-inset-top)` returns 0 if no inset, so
   the rule is safe to apply universally to standalone mode.
   ─── No layout shift ────────────────────────────────────────────────────
   Uses `box-sizing: border-box` so #root's existing `min-height: 100%`
   absorbs the padding inside its own height — content area shrinks by
   safe-area amount, no overflow, no double-scroll.
   ═══════════════════════════════════════════════════════════════════════ */
@media (display-mode: standalone) {
  /* Push React app content below the status bar.
     ─── Spacing tuning (2026-04-22) ────────────────────────────────────
     TOP: subtract 10px from full safe-area-inset-top because React Native
     Web bundle already adds its own ~30px page-header padding. Without
     subtraction, total top space = env() (47-59px) + React's 30px = too
     much empty space above page titles (Progress / Exercise / Skin / etc).
     `max(..., 0px)` floor keeps it safe on devices without inset (env=0).
     The 10px shave still leaves 37-49px clearance above the notch/island,
     which is well outside the iPhone 15 Pro dynamic-island geometry
     (island ends at y≈43px, our padding starts at y≥37px → safe gap).
     BOTTOM: 0. Tab bar has its own `padding-bottom: max(env(...), 6px)`
     (via the .nav[role=tablist] rule below) which keeps icons/labels
     above the home indicator. With #root padding-bottom: 0, the tab
     bar BACKGROUND extends edge-to-edge to device bottom (standard iOS
     app pattern: Twitter/Instagram/etc) — visually tighter, no float
     gap, and home indicator still clears the icons. */
  #root {
    padding-top: max(env(safe-area-inset-top) - 10px, 0px) !important;
    padding-bottom: 0 !important;
    box-sizing: border-box !important;
  }
  /* Standalone-only pages without #root (admin / exercise / money-maxxing /
     pay-test). Same tuning. */
  body:not(:has(#root)) {
    padding-top: max(env(safe-area-inset-top) - 10px, 0px) !important;
    padding-bottom: 0 !important;
    box-sizing: border-box !important;
  }
}

/* iOS-specific safety net: even if @media (display-mode: standalone) is
   misreported on some old WebKit versions, this @supports check matches
   only iOS Safari/WebKit. Same shave applied. */
@supports (-webkit-touch-callout: none) {
  @media (display-mode: standalone) {
    #root {
      padding-top: max(env(safe-area-inset-top, 47px) - 10px, 0px) !important;
    }
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LUXURY THEME UPGRADE (2026-04-22)
   ─── Goal ──────────────────────────────────────────────────────────────
   Transform the look from "generic dark" to "luxury / premium / lookmax"
   without changing ANY structure, behavior, or functionality. Pure CSS
   styling overlay on top of React's rendered DOM.
   ─── Constraints ───────────────────────────────────────────────────────
   • No backdrop-filter (already killed for perf)
   • No large shadows / blur (perf rules)
   • No structural changes (only colors / typography / spacing / borders)
   • Keep React's class names + inline styles untouched — overlay via
     attribute selectors + !important
   ─── Palette ───────────────────────────────────────────────────────────
   Background:    #0A0A0A (deep premium black)
   Surface base:  #16131e (warmer card surface, single tone)
   Surface raise: #1c1825 (slight elevation)
   Gold primary:  #D4A94F (refined, less saturated than orange)
   Gold light:    #F5C76A (highlights / large numbers)
   Gold deep:     #B7892E (active / pressed)
   Hairline:      rgba(212,169,79,0.14) (gold-tinted card borders)
   Text primary:  #F2F0EA (warm off-white)
   Text secondary:#A0A0A0
   Text muted:    #6F6B7A
   ═══════════════════════════════════════════════════════════════════════ */

/* (LUX 1) Body / shell — deep premium black instead of dark purple */
html, body {
  background: #0A0A0A !important;
  background-color: #0A0A0A !important;
  background-image: none !important;
  color: #F2F0EA !important;
  font-feature-settings: "ss01" on, "cv11" on, "tnum" on, "kern" on !important;
  -webkit-font-smoothing: antialiased !important;
  text-rendering: optimizeLegibility !important;
}

/* (LUX 2) Cards — warmer single-tone surface + gold-tinted hairline border.
   Targets the same Expo View patterns we already styled in index.html and
   the cards in admin/exercise/money-maxxing/pay-test. */
[style*="background-color: rgb(16, 16, 26)"],
[style*="background-color: rgb(26, 26, 40)"],
[style*="background-color: rgb(18, 18, 28)"],
[style*="background-color: rgb(14, 12, 30)"],
[style*="background-color:#10101a"],
[style*="background-color:#1a1a28"],
[style*="backgroundColor: rgb(16, 16, 26)"],
.tier-bar, .stat-card, .ref-card, .wd-card, .holding-note,
.exer-card, .rank-overall, .today-plan, .rest-box,
[class*="card"]:not([class*="discard"]):not([class*="picker"]):not([class*="card-"]) {
  background: #16131e !important;
  background-color: #16131e !important;
  background-image: none !important;
  border: 1px solid rgba(212,169,79,0.14) !important;
  border-radius: 18px !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.04),
    0 2px 8px rgba(0,0,0,0.35) !important;
}

/* (LUX 3) Tab bar — anchored to bottom with gold-tinted top hairline */
nav[role="tablist"],
[class*="tabbar"],
[class*="TabBar"] {
  background: #0A0A0A !important;
  background-color: #0A0A0A !important;
  border-top: 1px solid rgba(212,169,79,0.18) !important;
  box-shadow: 0 -1px 0 rgba(0,0,0,0.5) !important;
  padding-bottom: max(env(safe-area-inset-bottom), 6px) !important;
}

/* (LUX 4) Active tab label — premium gold (was orange #ffb347) */
nav[role="tablist"] [role="tab"][aria-selected="true"] *,
[class*="TabBar"] [aria-selected="true"] *,
[class*="tabbar"] [aria-selected="true"] * {
  color: #D4A94F !important;
}
/* Active tab dot indicator */
nav[role="tablist"] [role="tab"][aria-selected="true"] [class*="dot"],
[class*="TabBar"] [aria-selected="true"] [class*="dot"],
nav[role="tablist"] [role="tab"][aria-selected="true"]::after {
  background: #D4A94F !important;
}

/* (LUX 5) Inactive tabs — refined cool grey, balanced contrast */
nav[role="tablist"] [role="tab"]:not([aria-selected="true"]) *,
[class*="TabBar"] [aria-selected="false"] *,
[class*="tabbar"] [aria-selected="false"] * {
  color: #8A8597 !important;
}

/* (LUX 6) Hero numbers — tabular figures + gold + tighter tracking.
   Targets RN-Web inline 32px/40px score numbers we already bumped. */
div.css-146c3p1[style*="font-size: 32px"],
div.css-146c3p1[style*="font-size:32px"],
div.css-146c3p1[style*="font-size: 40px"],
div.css-146c3p1[style*="font-size:40px"] {
  color: #F5C76A !important;
  font-feature-settings: "tnum" on !important;
  font-variant-numeric: tabular-nums !important;
  letter-spacing: -0.03em !important;
  font-weight: 900 !important;
}

/* (LUX 7) Primary CTA buttons — premium gold gradient (was generic orange).
   Targets the big share button + premium "ปลดล็อก" buttons. */
[data-dd-share-btn="1"] {
  background: linear-gradient(135deg, #D4A94F 0%, #B7892E 100%) !important;
  background-color: #B7892E !important;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.18),
    0 4px 12px rgba(183,137,46,0.30) !important;
  border: none !important;
}
[data-dd-share-btn="1"] * {
  color: #1a1410 !important;
  text-shadow: none !important;
  letter-spacing: 0.5px !important;
  font-weight: 800 !important;
}

/* (LUX 7.9) Money Maxxing — nuke any element JS marked hidden (defense-in-depth).
   IMPORTANT: never apply to html/body/main — would black-screen the whole app.
   The :not() guards prevent the descendant rule from cascading into root. */
[data-mm-hidden="1"]:not(html):not(body):not(main),
#mm-profile-item {
  display: none !important;
  visibility: hidden !important;
  height: 0 !important;
  width: 0 !important;
  overflow: hidden !important;
  pointer-events: none !important;
  opacity: 0 !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* (LUX 8) Stripe / Pay buttons — VIBRANT colorful gradients (restored 2026-04-29).
   Earlier "subtle premium tone" override removed per user feedback —
   payment system should feel bright and inviting. */
.dd-pay-btn, .dd-stripe-btn {
  border-radius: 14px !important;
  border: 1.5px solid rgba(255,255,255,0.22) !important;
  letter-spacing: 0.2px !important;
  font-weight: 800 !important;
  color: #ffffff !important;
}
#dd-pay-card {
  background: linear-gradient(135deg, #635bff 0%, #5046e5 60%, #3b34c9 100%) !important;
  box-shadow:
    0 10px 28px rgba(80,70,229,.45),
    0 2px 0 rgba(255,255,255,.25) inset !important;
}
#dd-pay-promptpay {
  background: linear-gradient(135deg, #00a8ff 0%, #0064c8 100%) !important;
  box-shadow:
    0 10px 28px rgba(0,100,200,.45),
    0 2px 0 rgba(255,255,255,.25) inset !important;
}
#dd-pay-angpao {
  background: linear-gradient(135deg, #ff5758 0%, #c92a2a 100%) !important;
  box-shadow:
    0 10px 28px rgba(200,40,40,.45),
    0 2px 0 rgba(255,255,255,.25) inset !important;
}

/* (LUX 9) Money Maxxing card — refined gold ring, less neon-purple */
#mm-profile-item {
  background: linear-gradient(135deg, #1f1a2a 0%, #16131e 100%) !important;
  border: 1px solid rgba(212,169,79,0.30) !important;
  box-shadow:
    inset 0 0 0 1px rgba(212,169,79,0.10),
    inset 0 1px 0 rgba(255,255,255,0.06),
    inset 0 -8px 20px rgba(212,169,79,0.06) !important;
}
#mm-profile-item:hover {
  border-color: rgba(212,169,79,0.45) !important;
  box-shadow:
    inset 0 0 0 1px rgba(212,169,79,0.18),
    inset 0 1px 0 rgba(255,255,255,0.08),
    inset 0 -10px 22px rgba(212,169,79,0.12) !important;
}
#mm-profile-item .mm-earn-badge {
  background: rgba(212,169,79,0.10) !important;
  border-color: rgba(212,169,79,0.28) !important;
  color: #F5C76A !important;
}

/* (LUX 10) Premium / plan badges — refined gold instead of saturated orange */
[style*="rgb(245, 158, 11)"],
[style*="rgb(240, 192, 64)"],
[style*="#f59e0b"],
[style*="#f0c040"] {
  color: #F5C76A !important;
}

/* (LUX 11) Locked overlay — refined dark gradient, gold hairline */
.dd-locked-overlay-fix {
  background: linear-gradient(180deg,
    transparent 0%,
    rgba(10,10,10,0.65) 35%,
    rgba(10,10,10,0.96) 75%,
    rgba(10,10,10,0.99) 100%) !important;
  border-top: 1px solid rgba(212,169,79,0.10) !important;
}

/* (LUX 12) Exercise rank header — gold not orange */
.header h1, .cam-title {
  color: #F5C76A !important;
  letter-spacing: 2.5px !important;
  text-shadow: none !important;
}
.streak-badge {
  background: #1a1410 !important;
  border-color: #B7892E !important;
}
.streak-badge span {
  color: #F5C76A !important;
  text-shadow: none !important;
}

/* (LUX 13) "Tier color" / rank badges — gold tone replaces hot purple */
.rank-name {
  color: #F5C76A !important;
  text-shadow: none !important;
  letter-spacing: 4px !important;
  font-weight: 900 !important;
}
.rank-prog-bar {
  background: linear-gradient(90deg, #B7892E, #D4A94F, #F5C76A) !important;
  box-shadow: none !important;
}
.tab.active {
  border-color: #D4A94F !important;
  color: #D4A94F !important;
  background: #181420 !important;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04) !important;
}

/* (LUX 14) Section labels — refined small caps + gold accent
   Targets common uppercase section headers like "RECENT SCANS",
   "TODAY'S PLAN", "EXERCISE RANK", "SKINCARE", etc. */
[style*="letter-spacing: 2px"],
[style*="letter-spacing:2px"],
[class*="section-title"],
.tp-title, .cam-setup-title {
  color: #D4A94F !important;
  letter-spacing: 1.8px !important;
  font-weight: 700 !important;
  text-shadow: none !important;
}

/* (LUX 15) Pay-test page — refined surface */
.wrap .card {
  background: #16131e !important;
  border: 1px solid rgba(212,169,79,0.14) !important;
}
.wrap h1 {
  background: linear-gradient(90deg, #F5C76A 0%, #D4A94F 60%, #B7892E 100%) !important;
  -webkit-background-clip: text !important;
  background-clip: text !important;
  color: transparent !important;
  -webkit-text-fill-color: transparent !important;
}

/* (LUX 16) Refined PWA install banner */
#dd-pwa-install {
  background: linear-gradient(180deg, #1c1825 0%, #14101c 100%) !important;
  border: 1px solid rgba(212,169,79,0.22) !important;
  box-shadow: 0 8px 20px rgba(0,0,0,0.45) !important;
}
#dd-pwa-install .dd-pwa-yes {
  background: linear-gradient(135deg, #D4A94F, #B7892E) !important;
  color: #1a1410 !important;
}

/* (LUX 17) Lang toggle — refined gold pill */
#dd-lang-toggle {
  background: rgba(22,19,30,0.95) !important;
  border-color: rgba(212,169,79,0.22) !important;
}
#dd-lang-toggle button.active {
  background: linear-gradient(135deg, #D4A94F, #B7892E) !important;
  color: #1a1410 !important;
  box-shadow: 0 2px 6px rgba(183,137,46,0.30) !important;
}

/* (LUX 18) Selection color — gold */
::selection {
  background: rgba(212,169,79,0.30) !important;
  color: #F2F0EA !important;
}

/* (LUX 19) Scrollbar — refined gold thumb */
* {
  scrollbar-color: rgba(212,169,79,0.30) transparent !important;
}
*::-webkit-scrollbar-thumb {
  background: rgba(212,169,79,0.30) !important;
}
*::-webkit-scrollbar-thumb:hover {
  background: rgba(212,169,79,0.50) !important;
}

/* (LUX 20) Generous tap targets + line-height for premium feel */
:where(button, [role="button"]) {
  letter-spacing: 0.2px !important;
}

/* (LUX 21) Premium-modal Stripe wrapper refinement */
.dd-stripe-embedded-wrap {
  background: #16131e !important;
  border: 1px solid rgba(212,169,79,0.16) !important;
  box-shadow: 0 4px 12px rgba(0,0,0,0.32) !important;
}
.dd-stripe-embedded-title {
  color: #F5C76A !important;
}
.dd-stripe-embedded-sub {
  color: #A0A0A0 !important;
}

/* ─────────────────────────────────────────────────────────────────────
   Header icon theme polish — clock (history) + gear (settings).
   v2 2026-04-28: dropped :has() (iOS Safari < 16.4 doesn't support).
   paywall-polish.js tags icon buttons with .dd-icon-btn so this works
   on every browser including older iOS.
   ───────────────────────────────────────────────────────────────────── */
.dd-icon-btn {
  border-color: rgba(245, 199, 106, 0.55) !important;
  background: linear-gradient(135deg,
              rgba(245, 199, 106, 0.12),
              rgba(120, 80, 30, 0.06)) !important;
  background-image: linear-gradient(135deg,
              rgba(245, 199, 106, 0.12),
              rgba(120, 80, 30, 0.06)) !important;
  box-shadow:
    0 0 0 1px rgba(245, 199, 106, 0.40),
    0 4px 14px rgba(245, 199, 106, 0.22),
    inset 0 1px 0 rgba(255, 220, 150, 0.20) !important;
  transition: transform 0.15s ease, box-shadow 0.2s ease !important;
}
.dd-icon-btn svg,
.dd-icon-btn svg * {
  filter: drop-shadow(0 0 4px rgba(245, 199, 106, 0.65))
          drop-shadow(0 0 10px rgba(245, 199, 106, 0.30)) !important;
  color: #f5c76a !important;
  stroke: #f5c76a !important;
}
.dd-icon-btn:hover, .dd-icon-btn:active {
  transform: translateY(-1px) !important;
  box-shadow:
    0 0 0 1px rgba(245, 199, 106, 0.75),
    0 6px 20px rgba(245, 199, 106, 0.40),
    inset 0 1px 0 rgba(255, 220, 150, 0.28) !important;
}

/* ═══════════════════════════════════════════════════════════════════
 * UPLOAD-ICON SHAPE + UNIFORM SIZE (2026-04-30)
 * User report: "color season มันไม่กลม" + "ai analye มันต้องความสูงเดียว
 * กัน วงกลม ความสูงเดียวกัน" — across the 4 analysis tabs (Skin / Body
 * Fat / Color Season / Hair) the AI ANALYSIS badge + round icon must
 * render at the same height so the layout looks uniform. Force every
 * img / svg / halo / icon wrapper to a single 120 × 120 circle.
 * ═══════════════════════════════════════════════════════════════════ */

/* The halo wrapper (when tagger injects one) — fixed size circle */
[data-dd-upload-card] [data-dd-upload-icon-halo] {
  width: 120px !important;
  height: 120px !important;
  min-width: 120px !important;
  min-height: 120px !important;
  aspect-ratio: 1 / 1 !important;
  border-radius: 50% !important;
}

/* React's <img> AI illustration (Color Season tab) — match halo size +
   apply the same gold gradient halo as the wrapper, since it has no
   wrapping halo div from the tagger. */
[data-dd-upload-card] img {
  width: 120px !important;
  height: 120px !important;
  min-width: 120px !important;
  min-height: 120px !important;
  aspect-ratio: 1 / 1 !important;
  border-radius: 50% !important;
  object-fit: contain !important;
  padding: 14px !important;
  box-sizing: border-box !important;
  background: radial-gradient(circle at 50% 50%,
                rgba(251,191,36,0.18) 0%,
                rgba(139,77,255,0.10) 60%,
                transparent 100%) !important;
  box-shadow: 0 0 24px rgba(251,191,36,0.30),
              inset 0 0 16px rgba(251,191,36,0.10) !important;
  border: 1.5px solid rgba(251,191,36,0.45) !important;
}

/* SVG camera/body icons (other tabs) — sit centered inside the 120px
   halo at the standard 48px icon size. */
[data-dd-upload-card] svg,
[data-dd-upload-card] [data-dd-upload-icon] {
  width: 48px !important;
  height: 48px !important;
  aspect-ratio: 1 / 1 !important;
}

/* AI ANALYSIS badge — uniform height across tabs (matches design-system
   token of 5px 14px padding + 10px font, but force min-height so a
   line-height regression on one tab can't shrink the badge). */
[data-dd-ai-badge] {
  min-height: 24px !important;
  height: 24px !important;
  line-height: 14px !important;
  box-sizing: border-box !important;
}

/* ═══════════════════════════════════════════════════════════════════
 * 2026-04-30 — REMOVE PROFILE-INJECTED ICONS
 * User report: "เอารูปพวกนี้ออก" — the floating circle icons that
 * profile-premium-icons.js injects above the Premium Monthly + เชิญเพื่อน
 * cards (and the achievement-pill icons) were unwanted clutter. Hide
 * every injected icon host so the cards show their native React UI only.
 * ═══════════════════════════════════════════════════════════════════ */
.dd-profile-generated-icon,
.dd-profile-inline-icon-wrap,
[data-dd-profile-icon-host] .dd-profile-generated-icon,
[data-dd-profile-inline-iconized] > .dd-profile-inline-icon-wrap {
  display: none !important;
}

/* ═════════════════════════════════════════════════════════════════════
 * GLOW UP ROADMAP — chunkier rows + category emoji badge on the right.
 * Tagging happens in roadmap-enhance.js (data-dd-roadmap-item="1" +
 * data-dd-icon="🧴|💇|💪|..."). Pure decoration.
 * ═════════════════════════════════════════════════════════════════════ */
[data-dd-roadmap-item="1"] {
  padding: 14px 60px 14px 14px !important;
  margin: 8px 0 !important;
  position: relative !important;
  border-radius: 14px !important;
  background: linear-gradient(135deg, rgba(167,139,250,0.10), rgba(245,197,66,0.04)) !important;
  border: 1px solid rgba(167,139,250,0.22) !important;
  min-height: 68px !important;
  box-shadow:
    0 4px 14px rgba(0,0,0,0.22),
    inset 0 1px 0 rgba(255,255,255,0.05) !important;
  font-size: 14px !important;
  line-height: 1.55 !important;
}
[data-dd-roadmap-item="1"]::after {
  content: attr(data-dd-icon);
  position: absolute !important;
  right: 12px !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  width: 40px !important;
  height: 40px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-size: 22px !important;
  line-height: 1 !important;
  background: radial-gradient(circle at 35% 30%, #4a3478, #1f1140 70%) !important;
  border-radius: 50% !important;
  border: 1px solid rgba(245,197,66,0.45) !important;
  box-shadow:
    0 0 16px rgba(167,139,250,0.30),
    0 0 28px rgba(245,197,66,0.15),
    inset 0 0 8px rgba(255,255,255,0.06) !important;
  pointer-events: none !important;
}
