/* ============================================================
   DevcomClub Design System — Premium Glassmorphism Theme
   ============================================================ */

/* Prompt (loopless/ไม่มีหัว Thai) is the default UI font — admin-changeable via
   settings-mgmt.html "ฟอนต์เว็บไซต์", which loads any other thai-web-fonts CDN font on
   demand and points --font-thai at it (see THAI_FONTS/applyThaiFont() in js/db.js). */
@import url('https://cdn.jsdelivr.net/gh/lazywasabi/thai-web-fonts@7/fonts/Prompt/Prompt.css');
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  /* Default Colors (Will be overridden by DB settings) */
  --bg-color: #0a0f1d;
  --primary-color: #003366;
  --secondary-color: #00aaff;
  
  --primary-gradient: linear-gradient(135deg, var(--primary-color) 0%, #001f4d 100%);
  --secondary-gradient: linear-gradient(135deg, var(--secondary-color) 0%, #0077b6 100%);
  --accent-gradient: linear-gradient(135deg, #00aaff 0%, #00f2fe 100%);
  
  /* Text and Card Overlays */
  --text-main: #ffffff;
  --text-muted: #94a3b8;

  /* --- Liquid Glass tuning knobs — admin-adjustable from settings-mgmt.html (see
     applySystemSettings() in db.js, which overwrites these three via
     document.documentElement.style.setProperty, same mechanism as the theme colors above).
     Everything glass-related derives from these three instead of hardcoding its own numbers,
     so one set of sliders actually controls the whole look. ---
     --glass-opacity: 0..1, how see-through the glass fill is (higher = more opaque/frosted)
     --glass-blur: backdrop blur radius on the three big surfaces (card-panel/sidebar/glass-card)
     --glass-sheen-strength: 0..1, peak brightness of the specular highlight pool
     --glass-sheen-color-rgb: "R, G, B" (no rgb()/rgba() wrapper) tint of that highlight — kept
     as bare components rather than a hex/color value so it can slot straight into the rgba()
     calls below; admin picks a hex color in settings-mgmt.html and applySystemSettings() (db.js)
     converts it to this "R, G, B" form before setting the custom property. */
  --glass-opacity: 0.45;
  --glass-blur: 32px;
  --glass-sheen-strength: 0.30;
  --glass-sheen-color-rgb: 255, 255, 255;

  --bg-glass: rgba(15, 23, 42, var(--glass-opacity));
  --bg-glass-hover: rgba(30, 41, 59, calc(var(--glass-opacity) + 0.15));
  --border-glass: rgba(255, 255, 255, 0.08);
  --border-focus: rgba(0, 170, 255, 0.5);

  /* "Liquid Glass" specular highlight — the soft bright pool near one corner + a fainter
     diagonal sheen is what actually reads as "curved glass catching light" rather than plain
     frosted-glass blur. Layer this as the first (topmost) background image on any glass surface:
     background: var(--glass-sheen), var(--bg-glass); — stacks fine, no pseudo-element/overflow
     needed since background-image already clips to the element's own border-radius. */
  --glass-sheen:
    radial-gradient(120% 100% at 18% -15%, rgba(var(--glass-sheen-color-rgb), var(--glass-sheen-strength)), transparent 55%),
    linear-gradient(155deg, rgba(var(--glass-sheen-color-rgb), calc(var(--glass-sheen-strength) * 0.4)) 0%, transparent 45%);
  --glass-sheen-hover:
    radial-gradient(120% 100% at 18% -15%, rgba(var(--glass-sheen-color-rgb), calc(var(--glass-sheen-strength) + 0.1)), transparent 58%),
    linear-gradient(155deg, rgba(var(--glass-sheen-color-rgb), calc(var(--glass-sheen-strength) * 0.53)) 0%, transparent 45%);

  /* Shadows and Radii */
  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 48px 0 rgba(0, 0, 0, 0.5);
  
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --radius-full: 9999px;
  
  --transition-fast: 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  --transition-normal: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* --- Ambient animated background (shared across all pages) ---
   Any element that must sit above this layer needs position:relative + z-index:1+ */
.bg-orb {
  position: fixed;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.35;
  pointer-events: none;
  z-index: 0;
  will-change: transform, opacity;
}

.bg-orb.orb-1 {
  width: 520px;
  height: 520px;
  top: -180px;
  left: -150px;
  background: radial-gradient(circle, var(--secondary-color) 0%, rgba(0, 170, 255, 0.1) 70%);
  animation: orbDrift1 18s ease-in-out infinite alternate, orbPulse 8s ease-in-out infinite alternate;
}

.bg-orb.orb-2 {
  width: 480px;
  height: 480px;
  bottom: -180px;
  right: -140px;
  background: radial-gradient(circle, var(--primary-color) 0%, rgba(0, 51, 102, 0.2) 70%);
  animation: orbDrift2 22s ease-in-out infinite alternate, orbPulse 10s ease-in-out infinite alternate;
}

.bg-orb.orb-3 {
  width: 320px;
  height: 320px;
  top: 45%;
  left: 55%;
  background: radial-gradient(circle, #00f2fe 0%, rgba(0, 242, 254, 0.05) 70%);
  opacity: 0.22;
  animation: orbDrift3 26s ease-in-out infinite alternate, orbPulse 6s ease-in-out infinite alternate;
}

.bg-orb.orb-4 {
  width: 380px;
  height: 380px;
  top: 20%;
  right: 15%;
  background: radial-gradient(circle, #7928ca 0%, rgba(121, 40, 202, 0.08) 70%);
  opacity: 0.25;
  animation: orbDrift4 20s ease-in-out infinite alternate, orbPulse 12s ease-in-out infinite alternate;
}

@keyframes orbDrift1 {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(80px, 50px) scale(1.12); }
  100% { transform: translate(-30px, 80px) scale(0.95); }
}

@keyframes orbDrift2 {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-70px, -40px) scale(1.15); }
  100% { transform: translate(40px, -60px) scale(0.92); }
}

@keyframes orbDrift3 {
  0% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-60px, 45px) scale(1.2); }
  100% { transform: translate(50px, -35px) scale(0.88); }
}

@keyframes orbDrift4 {
  0% { transform: translate(0, 0) scale(0.9); }
  50% { transform: translate(50px, -50px) scale(1.1); }
  100% { transform: translate(-40px, 40px) scale(1); }
}

@keyframes orbPulse {
  0%, 100% { opacity: 0.25; filter: blur(85px); }
  50% { opacity: 0.45; filter: blur(105px); }
}

/* Admin pages (.admin-layout) have two things eating into how much of the orb glow actually
   reaches the eye that the public site doesn't: a fixed, blurred sidebar sitting directly over
   orb-1's home position (top-left), and most of the visible canvas being filled with .card-panel
   glass (itself blurred) rather than bare background. Nudge orb-1 out from behind the sidebar
   into the open content area, and boost every orb's opacity so the ambient light still reads
   through the heavier layered blur instead of washing out to almost nothing. */
body:has(.admin-layout) .bg-orb.orb-1 {
  left: 220px;
  opacity: 0.5;
}
body:has(.admin-layout) .bg-orb.orb-2 { opacity: 0.5; }
body:has(.admin-layout) .bg-orb.orb-3 { opacity: 0.38; }
body:has(.admin-layout) .bg-orb.orb-4 { opacity: 0.4; }

.bg-grid {
  position: fixed;
  inset: 0;
  z-index: 0;
  background-image:
    linear-gradient(rgba(0, 170, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 170, 255, 0.04) 1px, transparent 1px);
  background-size: 48px 48px;
  -webkit-mask-image: radial-gradient(circle at 50% 40%, #000 10%, transparent 75%);
  mask-image: radial-gradient(circle at 50% 40%, #000 10%, transparent 75%);
  pointer-events: none;
  animation: gridGlow 12s ease-in-out infinite alternate;
}

@keyframes gridGlow {
  0% { opacity: 0.6; transform: scale(1); }
  50% { opacity: 0.9; transform: scale(1.01); }
  100% { opacity: 0.6; transform: scale(1); }
}

/* --- HUD Loop Background Effect ---
   Toggle-controlled (hero_effect_enabled / admin_effect_enabled in site_settings, applied by
   applySystemSettings() in db.js, which injects/removes this markup entirely rather than just
   hiding it — no cost when the admin leaves it off). Ken Burns pan/zoom on the already-configured
   background image, plus a few staggered "terminal readout" panels fading in and out, standing in
   for the sci-fi HUD look from the reference mockup. .hud-fx-layer sits behind everything in its
   host (hero section = relative + overflow:hidden already; admin = position:fixed like .bg-orb). */
.hud-fx-layer {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  /* Fades the top ~14% of the layer to transparent so the Ken Burns image visibly recedes under
     the sticky translucent header instead of looking like it bleeds straight past the boundary. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 14%, #000 100%);
}
.hud-fx-layer.hud-fx-fixed {
  position: fixed;
  z-index: 0;
  -webkit-mask-image: none;
  mask-image: none;
}
.hud-fx-bg {
  position: absolute;
  inset: -6%;
  /* --hud-fx-bg-size / --hud-fx-zoom: admin-adjustable (settings-mgmt.html "ขนาดพื้นหลังเอฟเฟกต์"),
     applied by applySystemSettings() — cover/contain fit plus a zoom multiplier so an oversized or
     awkwardly-cropped source image can be dialed back without touching the actual site background. */
  background-size: var(--hud-fx-bg-size, cover);
  background-position: center;
  opacity: 0.5;
  filter: saturate(1.15) brightness(0.85);
  transform: scale(var(--hud-fx-zoom, 1));
  animation: hudKenburns 24s ease-in-out infinite alternate;
}
/* A fully-transparent center (the old 0% stop) let raw, un-dimmed background show through
   untouched wherever no glass panel happened to sit over it — e.g. the empty space below a
   short table on a mostly-empty admin page — which read as jarringly bright/sharp next to the
   heavily blurred, tinted cards elsewhere on the same page ("พื้นหลังไม่เต็ม" — feels patchy/
   unfinished rather than one consistent backdrop). A small always-on tint at center keeps the
   image/video toned down everywhere, not just at the edges. */
.hud-fx-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, rgba(4, 10, 20, 0.25) 0%, rgba(4, 10, 20, 0.72) 100%);
}
@keyframes hudKenburns {
  from { transform: scale(var(--hud-fx-zoom, 1)) translate(0, 0); }
  to { transform: scale(calc(var(--hud-fx-zoom, 1) * 1.06)) translate(-1.2%, -1%); }
}

.hud-fx-panel {
  position: absolute;
  font-family: 'JetBrains Mono', 'Courier New', monospace;
  font-size: 0.68rem;
  line-height: 1.55;
  color: rgba(140, 225, 255, 0.9);
  background: rgba(4, 10, 20, 0.55);
  border: 1px solid rgba(0, 204, 255, 0.25);
  border-radius: 8px;
  padding: 8px 12px;
  white-space: pre;
  opacity: 0;
  backdrop-filter: blur(4px);
  box-shadow: 0 0 20px rgba(0, 204, 255, 0.08);
  animation: hudPanelFade 9s ease-in-out infinite;
}
.hud-fx-panel:nth-of-type(1) { top: 9%; left: 4%; animation-delay: 0s; }
.hud-fx-panel:nth-of-type(2) { top: 12%; right: 4%; animation-delay: 2.2s; }
.hud-fx-panel:nth-of-type(3) { bottom: 14%; left: 4%; animation-delay: 4.4s; }
.hud-fx-panel:nth-of-type(4) { bottom: 9%; right: 4%; animation-delay: 6.6s; }

@keyframes hudPanelFade {
  0%, 100% { opacity: 0; transform: translateY(6px); }
  12% { opacity: 1; transform: translateY(0); }
  78% { opacity: 1; }
  92% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hud-fx-bg, .hud-fx-panel { animation: none !important; }
}
@media (max-width: 768px) {
  .hud-fx-panel { display: none; }
}

/* --- Submit button loading state (shared) --- */
.btn-submit-spinner {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #ffffff;
  animation: spin-loader 0.7s linear infinite;
  display: none;
}
@keyframes spin-loader {
  to { transform: rotate(360deg); }
}
.btn.is-loading .btn-submit-spinner {
  display: inline-block;
}
.btn.is-loading .btn-submit-label {
  opacity: 0.85;
}

/* --- Reset & Base --- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Without this, any <img> lacking its own explicit width/height (or a stray/misconfigured one)
   renders at native pixel size and can blow out its container — a classic overflow source.
   Component rules with a class selector (e.g. .news-gallery-slide) are more specific and win over this. */
img {
  max-width: 100%;
  height: auto;
}

html {
  scroll-behavior: smooth;
  font-size: 16px;
}

body {
  font-family: var(--font-thai, 'Prompt'), 'Inter', system-ui, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-main);
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--secondary-color);
  text-decoration: none;
  transition: all var(--transition-fast);
}

a:hover {
  filter: brightness(1.2);
}

/* --- Scrollbar --- */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: var(--bg-color);
}
::-webkit-scrollbar-thumb {
  background: var(--primary-color);
  border-radius: var(--radius-full);
  border: 2px solid var(--bg-color);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--secondary-color);
}

/* --- Typography --- */
h1, h2, h3, h4, h5, h6 {
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
}

/* --- Glassmorphism UI Components ---
   "Liquid Glass" pass (iOS 26+-style): var(--glass-sheen) is the specular highlight — the soft
   bright pool near one corner that actually reads as "curved glass catching light," layered as
   an extra background-image (clips to border-radius automatically, no pseudo-element/
   overflow:hidden needed) — plus heavier blur+saturate so color behind the pane shows through
   vivid instead of muddy, and a two-tone inset highlight (bright top edge, dark bottom edge)
   for the bevel. */
.glass-card {
  background: var(--glass-sheen), var(--bg-glass);
  backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(180%);
  border: 1px solid var(--border-glass);
  border-radius: var(--radius-lg);
  padding: 24px;
  box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.14), inset 0 -1px 0 rgba(0, 0, 0, 0.12);
  transition: all var(--transition-normal);
}

.glass-card:hover {
  background: var(--glass-sheen-hover), var(--bg-glass-hover);
  border-color: rgba(255, 255, 255, 0.15);
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.12);
}

/* --- Navigation Header --- */
header.main-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(10, 15, 29, 0.7);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border-glass);
  padding: 0 40px;
  min-height: 70px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.nav-toggle-btn {
  display: none;
  background: transparent;
  border: none;
  color: #ffffff;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: var(--radius-sm, 8px);
  flex-shrink: 0;
}
.nav-toggle-btn:hover {
  background: rgba(255, 255, 255, 0.08);
}

.nav-collapse {
  display: flex;
  align-items: center;
  gap: 24px;
  min-width: 0;
}

/* --- Floating "แจ้งเรื่อง" contact button — sticky bottom-right, follows scroll instead of
   being a section pinned at the bottom of the page (opens contact-modal on click). Same Liquid
   Glass treatment as .btn-primary (static sheen + hover sweep + bevel highlight) so it reads as
   part of the design system instead of a plain flat pill; a soft breathing glow ring behind it
   draws the eye without being a distracting animation. Icon is an inline SVG (not an emoji) so
   it never falls back to a blank glyph box on systems missing a color-emoji font. */
.contact-fab {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 150;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 22px;
  border-radius: var(--radius-full);
  background: var(--glass-sheen), var(--secondary-gradient);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: 0 8px 28px rgba(0, 170, 255, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.35), inset 0 -2px 4px rgba(0, 0, 0, 0.15);
  cursor: pointer;
  font-weight: 700;
  font-size: 0.9rem;
  font-family: inherit;
  overflow: hidden;
  transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.contact-fab::before {
  content: '';
  position: absolute;
  inset: -6px;
  border-radius: inherit;
  background: var(--secondary-color);
  filter: blur(14px);
  opacity: 0.55;
  z-index: -1;
  animation: fabGlowPulse 3.2s ease-in-out infinite;
}

.contact-fab::after {
  content: '';
  position: absolute;
  top: 0;
  left: -75%;
  width: 50%;
  height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: skewX(-20deg);
  transition: left 0.6s ease;
}

.contact-fab:hover::after {
  left: 125%;
}

.contact-fab:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 36px rgba(0, 170, 255, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4), inset 0 -2px 4px rgba(0, 0, 0, 0.15);
}

@keyframes fabGlowPulse {
  0%, 100% { opacity: 0.4; transform: scale(0.96); }
  50% { opacity: 0.7; transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
  .contact-fab::before { animation: none; }
}

.contact-fab-icon {
  display: flex;
  line-height: 1;
}
.contact-fab-icon svg {
  width: 19px;
  height: 19px;
  display: block;
}

@media (max-width: 640px) {
  .contact-fab {
    bottom: 16px;
    right: 16px;
    padding: 14px;
    border-radius: 50%;
  }
  .contact-fab-label {
    display: none;
  }
}

.logo-wrap {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo-img {
  height: 40px;
  width: auto;
}

.logo-title {
  font-size: 1.15rem;
  font-weight: 800;
  background: linear-gradient(to right, #ffffff, var(--secondary-color));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.nav-menu {
  display: flex;
  align-items: center;
  gap: 24px;
}

.nav-menu a {
  position: relative;
  color: var(--text-muted);
  font-weight: 500;
  font-size: 0.95rem;
  transition: color var(--transition-fast);
}

.nav-menu a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -6px;
  width: 100%;
  height: 2px;
  background: var(--secondary-gradient);
  border-radius: var(--radius-full);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--transition-normal);
}

.nav-menu a:hover, .nav-menu a.active {
  color: var(--text-main);
  text-shadow: 0 0 10px rgba(0, 170, 255, 0.5);
}

.nav-menu a:hover::after, .nav-menu a.active::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* --- Buttons --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 24px;
  border-radius: var(--radius-full);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  border: 1px solid transparent;
  transition: all var(--transition-fast);
}

.btn-primary {
  position: relative;
  overflow: hidden;
  /* Static specular pool (var(--glass-sheen)) sits under the existing sweep animation below —
     Apple's Liquid Glass buttons carry a highlight even at rest, not only mid-hover-sweep. */
  background: var(--glass-sheen), var(--secondary-gradient);
  color: #ffffff;
  box-shadow: 0 4px 14px rgba(0, 170, 255, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.35), inset 0 -2px 4px rgba(0, 0, 0, 0.15);
}

.btn-primary::before {
  content: '';
  position: absolute;
  top: 0;
  left: -75%;
  width: 50%;
  height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-20deg);
  transition: left 0.6s ease;
}

.btn-primary:hover::before {
  left: 125%;
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 170, 255, 0.5);
}

.btn-secondary {
  background: var(--glass-sheen), var(--bg-glass);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  color: var(--text-main);
  border-color: var(--border-glass);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.btn-secondary:hover {
  background: var(--glass-sheen-hover), rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* Header "เข้าสู่ระบบ" CTA — plain .btn-secondary reads as flat/inert next to the glowing
   gradient buttons elsewhere, so this variant borrows the theme's cyan accent as an outline +
   soft glow instead: noticeable without the visual weight of a full gradient fill, appropriate
   for a small button that's always sitting in the header. */
.btn-login-cta {
  background: var(--glass-sheen), rgba(0, 170, 255, 0.08);
  border-color: rgba(0, 204, 255, 0.45);
  color: #ffffff;
  box-shadow: 0 0 16px rgba(0, 204, 255, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.15);
}

.btn-login-cta:hover {
  background: var(--glass-sheen-hover), rgba(0, 170, 255, 0.18);
  border-color: rgba(0, 204, 255, 0.75);
  box-shadow: 0 0 24px rgba(0, 204, 255, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.btn-accent {
  background: var(--glass-sheen), var(--accent-gradient);
  color: #000000;
  font-weight: 700;
  box-shadow: 0 4px 14px rgba(0, 242, 254, 0.3);
}

.btn-accent:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 242, 254, 0.5);
}

.btn-danger {
  background: rgba(239, 68, 68, 0.12);
  color: #f87171;
  border-color: rgba(239, 68, 68, 0.3);
}

.btn-danger:hover {
  background: rgba(239, 68, 68, 0.22);
  border-color: rgba(239, 68, 68, 0.5);
}

/* Compact variant for icon-only row actions (tables, media cards, folder trees) — without this,
   buttons like 🔗/📦/🗑️ render at full .btn size and overflow narrow flex rows */
.btn-sm {
  padding: 6px 12px;
  font-size: 0.78rem;
  gap: 4px;
}

.btn-block {
  width: 100%;
}

/* --- Hero Banner --- */
.hero-section {
  position: relative;
  z-index: 1;
  min-height: 560px;
  padding: 130px 40px 100px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  overflow: hidden;
  background:
    radial-gradient(circle at 28% 20%, rgba(0, 242, 254, 0.14) 0%, transparent 45%),
    radial-gradient(circle at 76% 12%, rgba(0, 170, 255, 0.18) 0%, transparent 50%),
    radial-gradient(circle at top, rgba(0, 170, 255, 0.15) 0%, transparent 60%);
  border-bottom: 1px solid var(--border-glass);
}

/* Fine dot texture, masked to a soft spotlight so it fades out toward the hero edges */
.hero-section::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(0, 170, 255, 0.18) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(circle at 50% 35%, #000 0%, transparent 65%);
  mask-image: radial-gradient(circle at 50% 35%, #000 0%, transparent 65%);
  pointer-events: none;
  z-index: -1;
}

/* Slow-spinning conic glow behind the title for a bit of depth beyond the flat radial wash */
.hero-section::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 640px;
  height: 640px;
  transform: translate(-50%, -55%);
  background: conic-gradient(from 0deg, rgba(0, 242, 254, 0.18), rgba(0, 170, 255, 0.04) 30%, transparent 55%, rgba(0, 170, 255, 0.12) 80%, rgba(0, 242, 254, 0.18));
  filter: blur(70px);
  opacity: 0.55;
  animation: heroRingSpin 26s linear infinite;
  pointer-events: none;
  z-index: -1;
}

@keyframes heroRingSpin {
  to { transform: translate(-50%, -55%) rotate(360deg); }
}

/* Holds 0..N .hero-eyebrow pills (admin-editable list, see banner_eyebrows in
   settings-mgmt.html / applySystemSettings()) — wraps and centers when there's more than one */
.hero-eyebrows {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-bottom: 24px;
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 18px;
  border-radius: var(--radius-full);
  background: var(--bg-glass);
  border: 1px solid var(--border-glass);
  color: var(--secondary-color);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  backdrop-filter: blur(10px);
}

.hero-eyebrow .hero-eyebrow-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #34d399;
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.8);
  animation: heroDotPulse 1.8s ease-in-out infinite;
}

@keyframes heroDotPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.75); }
}

.hero-cta-row {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Lower-emphasis hero action — keeps secondary lookups (card/ticket/verify) from competing
   visually with the primary "สมัครเข้าชมรม" CTA and the accent member-portal link */
.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-glass);
}

.btn-ghost:hover {
  color: var(--text-main);
  border-color: rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.04);
}

.hero-scroll-cue {
  position: absolute;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--text-muted);
  font-size: 1.1rem;
  opacity: 0.6;
  text-decoration: none;
  animation: heroScrollBounce 2.2s ease-in-out infinite;
}

.hero-scroll-cue:hover { opacity: 1; }

@keyframes heroScrollBounce {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 8px); }
}

.hero-title {
  font-size: clamp(2.2rem, 5vw, 3.8rem);
  font-weight: 800;
  margin-bottom: 20px;
  background: linear-gradient(135deg, #ffffff 30%, #a5f3fc 70%, var(--secondary-color) 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.hero-subtitle {
  font-size: 1.15rem;
  color: var(--text-muted);
  max-width: 700px;
  margin-bottom: 40px;
}

/* --- Layout Grid --- */
.container {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
  padding: 60px 20px;
}

.section-title {
  font-size: 1.8rem;
  margin-bottom: 30px;
  text-align: center;
  position: relative;
  display: inline-block;
  left: 50%;
  transform: translateX(-50%);
}

.section-title::after {
  content: '';
  position: absolute;
  bottom: -8px;
  left: 20%;
  right: 20%;
  height: 3px;
  background: var(--accent-gradient);
  border-radius: var(--radius-full);
}

.news-grid, .activities-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 24px;
}

/* --- News & Roadmap carousel (auto-slides, max 3 cards per page) --- */
.news-carousel-viewport {
  overflow: hidden;
  position: relative;
}

.news-carousel-track {
  display: flex;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.news-slide {
  flex: 0 0 100%;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 24px;
  align-items: stretch;
}

.news-page-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 20px;
}

.news-page-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.25);
  cursor: pointer;
  transition: all 0.25s ease;
}

.news-page-dot.active {
  background: var(--secondary-color, var(--primary-color));
  transform: scale(1.3);
}

/* --- Badges --- */
.badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: var(--radius-full);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  /* Small top-light bevel, same glass-bevel language as the bigger surfaces — cheap on a tiny
     pill (no room/need for the full blur+sheen treatment) but keeps it from feeling flat next to them. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.tag-blue { background: rgba(59, 130, 246, 0.2); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
.tag-cyan { background: rgba(6, 182, 212, 0.2); color: #22d3ee; border: 1px solid rgba(6, 182, 212, 0.3); }
.tag-gold { background: rgba(245, 158, 11, 0.2); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }
.tag-green { background: rgba(16, 185, 129, 0.2); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
.tag-red { background: rgba(239, 68, 68, 0.2); color: #f87171; border: 1px solid rgba(239, 68, 68, 0.3); }

/* Scoped pulse for "live" indicators (e.g. an OPEN activity badge) — not applied to every
   .tag-green, since that class is also used for plain static "approved/active" statuses */
.pulse-badge {
  position: relative;
  padding-left: 20px !important;
}

.pulse-badge::before {
  content: '';
  position: absolute;
  left: 8px;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  transform: translateY(-50%);
  animation: pulseBadgeDot 1.6s ease-in-out infinite;
}

@keyframes pulseBadgeDot {
  0% { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
  70% { box-shadow: 0 0 0 6px transparent; opacity: 0.6; }
  100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
}

/* --- News details gallery: single image or an auto-rotating fade carousel for 2+ images --- */
.news-gallery-single {
  width: 100%;
  max-height: 280px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  display: block;
}

.news-gallery-slides {
  position: relative;
  width: 100%;
  height: 280px;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.news-gallery-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.8s ease;
}

.news-gallery-slide.active {
  opacity: 1;
  pointer-events: auto;
}

.news-gallery-dots {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 10px;
}

.news-gallery-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  transition: all 0.25s ease;
}

.news-gallery-dot.active {
  background: var(--secondary-color);
  transform: scale(1.3);
}

/* --- Forms & Inputs --- */
.form-group {
  margin-bottom: 20px;
}

.form-label {
  display: block;
  font-size: 0.88rem;
  color: var(--text-muted);
  margin-bottom: 8px;
  font-weight: 500;
}

.form-control {
  width: 100%;
  background: rgba(10, 15, 29, 0.6);
  backdrop-filter: blur(12px) saturate(150%);
  -webkit-backdrop-filter: blur(12px) saturate(150%);
  border: 1px solid var(--border-glass);
  border-radius: 12px;
  padding: 12px 16px;
  color: #ffffff;
  font-family: inherit;
  font-size: 0.92rem;
  /* Faint inner shadow at the top + a hairline of light along the bottom edge — the same
     glass-bevel language as .glass-card/.card-panel, scaled down for a recessed field. */
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(255, 255, 255, 0.05);
  transition: all var(--transition-fast);
}

.form-control:focus {
  outline: none;
  border-color: var(--secondary-color);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(255, 255, 255, 0.05), 0 0 0 2px var(--border-focus);
}

/* --- Slide Drawer / Popup Modal --- */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(5, 8, 16, 0.85);
  backdrop-filter: blur(8px);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition-normal), visibility var(--transition-normal);
  visibility: hidden;
}

.modal-overlay.open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

/* Media-picker sits on top of any other open modal */
#media-picker-modal {
  z-index: 1100;
}

.modal-container {
  width: 90%;
  max-width: 520px;
  max-height: 88vh;
  overflow-y: auto;
  overflow-x: hidden;
  box-sizing: border-box;
  transform: translateY(20px);
  transition: transform var(--transition-normal);
}

.modal-overlay.open .modal-container {
  transform: translateY(0);
}

/* Prevent images inside modal from overflowing */
.modal-container img {
  max-width: 100% !important;
  box-sizing: border-box !important;
}

/* Slide Drawer Login */
.drawer {
  position: fixed;
  top: 0;
  right: -420px;
  width: 100%;
  max-width: 400px;
  height: 100vh;
  background: rgba(10, 15, 29, 0.95);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  border-left: 1px solid var(--border-glass);
  z-index: 1000;
  padding: 40px 24px;
  box-shadow: -10px 0 40px rgba(0, 0, 0, 0.5);
  transition: all var(--transition-normal);
  display: flex;
  flex-direction: column;
}

.drawer.open {
  right: 0;
}

/* --- Digital Member Card Style --- */
.member-card-wrapper {
  background: linear-gradient(135deg, #001f4d 0%, #0a0f1d 100%);
  border-radius: var(--radius-md);
  border: 1px solid rgba(0, 170, 255, 0.25);
  padding: 30px;
  position: relative;
  overflow: hidden;
  box-shadow: 0 15px 40px rgba(0, 0, 0, 0.6);
  aspect-ratio: 1.6 / 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.member-card-wrapper::after {
  content: 'DEVCOM';
  position: absolute;
  right: -20px;
  bottom: -20px;
  font-size: 5rem;
  font-weight: 900;
  opacity: 0.04;
  color: #ffffff;
  pointer-events: none;
}

.member-card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.member-card-body {
  margin-top: 20px;
  display: flex;
  justify-content: space-between;
  gap: 20px;
}

.member-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.member-name {
  font-size: 1.4rem;
  font-weight: 700;
  color: #ffffff;
}

.member-id {
  font-size: 0.9rem;
  color: var(--secondary-color);
  letter-spacing: 0.05em;
}

.member-major {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.member-qr {
  background: white;
  padding: 8px;
  border-radius: 8px;
  width: 90px;
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.member-qr img {
  width: 100%;
  height: 100%;
}

/* --- Tables & Tracking --- */
.table-responsive {
  width: 100%;
  overflow-x: auto;
}

table.custom-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  margin-top: 15px;
}

table.custom-table th, table.custom-table td {
  padding: 14px 18px;
  text-align: left;
  border-bottom: 1px solid var(--border-glass);
}

/* Sits inside a .card-panel, which already carries the blur/sheen — the header row just needs
   enough of its own tint + accent color to read as a distinct band on that glass, not a second
   full glass treatment layered on top. */
table.custom-table th {
  color: var(--secondary-color);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.06) 0%, rgba(255, 255, 255, 0.02) 100%);
}

table.custom-table thead tr:first-child th:first-child { border-top-left-radius: var(--radius-sm); }
table.custom-table thead tr:first-child th:last-child { border-top-right-radius: var(--radius-sm); }

table.custom-table tbody tr {
  transition: background-color var(--transition-fast);
}

table.custom-table tbody tr:hover {
  background: rgba(255, 255, 255, 0.045);
}

/* --- Footer --- */
footer.main-footer {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--border-glass);
  padding: 40px 20px;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* --- Alert Messages --- */
.alert-popup {
  position: fixed;
  bottom: 24px;
  right: 24px;
  padding: 16px 24px;
  border-radius: var(--radius-sm);
  z-index: 2000;
  box-shadow: var(--shadow-lg);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 12px;
  transform: translateY(100px);
  opacity: 0;
  transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.alert-popup.show {
  transform: translateY(0);
  opacity: 1;
}

.alert-popup.success {
  background: #064e3b;
  color: #a7f3d0;
  border: 1px solid #047857;
}

.alert-popup.error {
  background: #7f1d1d;
  color: #fca5a5;
  border: 1px solid #b91c1c;
}

/* --- Utilities --- */
.text-center { text-align: center; }
.mb-10 { margin-bottom: 10px; }
.mb-20 { margin-bottom: 20px; }
.mb-30 { margin-bottom: 30px; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.gap-10 { gap: 10px; }
.hidden { display: none !important; }

/* Responsive adjustments */
/* Below this width, the nav links + auth area (which grows to 3-4 extra buttons once logged
   in as staff — welcome text, dashboard, scan, logout) no longer fit the header in one row.
   They used to just wrap in place inside the fixed-height header, overlapping/clipping — now
   they collapse into a dropdown panel toggled by the ☰ button instead. */
@media (max-width: 1400px) {
  header.main-header {
    padding: 0 20px;
  }
  .nav-toggle-btn {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .nav-collapse {
    display: none;
    position: absolute;
    top: 70px;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 18px;
    padding: 20px;
    background: rgba(10, 15, 29, 0.97);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--border-glass);
    max-height: calc(100vh - 70px);
    overflow-y: auto;
  }
  .nav-collapse.open {
    display: flex;
  }
  .nav-menu {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  #auth-header-area {
    width: 100%;
  }
}

@media (max-width: 768px) {
  .hero-section {
    padding: 80px 20px 40px;
  }
  .hero-section::after {
    width: 420px;
    height: 420px;
  }
  .hero-scroll-cue {
    display: none;
  }
}

/* --- High Quality Premium Animations --- */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(24px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.animate-fade-in-up {
  animation: fadeInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.animate-fade-in {
  animation: fadeIn 0.4s ease both;
}

.animate-scale-in {
  animation: scaleIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

/* Delay modifiers */
.delay-100 { animation-delay: 100ms; }
.delay-200 { animation-delay: 200ms; }
.delay-300 { animation-delay: 300ms; }
.delay-400 { animation-delay: 400ms; }

/* Clean static hover for premium cards (No scale, no tilt, no image blur, sharp text readability) */
.glass-card {
  transition: border-color 0.3s ease, background-color 0.3s ease, box-shadow 0.3s ease !important;
}

.glass-card:hover {
  transform: none !important;
  border-color: rgba(0, 170, 255, 0.35) !important;
  box-shadow: 0 8px 30px rgba(0, 170, 255, 0.12), var(--shadow-md) !important;
}

/* --- Scroll-reveal (grid cards fade/slide in as they enter the viewport) --- */
.reveal-on-scroll {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal-on-scroll.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* --- News Card Image (หน้าหลัก) --- */
.news-card-img-wrap {
  width: 100% !important;
  max-width: 100% !important;
  height: 180px !important;
  max-height: 180px !important;
  overflow: hidden !important;
  flex-shrink: 0;
  position: relative;
  background: rgba(0, 0, 0, 0.2);
}

.news-card-img {
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  object-fit: cover !important;
  object-position: center top !important;
  display: block !important;
  /* "Ken Burns" drift — a living, cinematic cover instead of a static poster. Runs continuously
     (not hover-gated); the wrap's overflow:hidden clips the zoomed overflow. Starts mid-cycle
     (negative delay) so it's already visibly in motion on first paint, not sitting at scale(1). */
  animation: kenburns 10s ease-in-out infinite alternate;
  animation-delay: -3s;
  animation-play-state: running;
}

/* A little desync across a grid of cards so they don't all breathe in lockstep — targets the
   card's position among its siblings (.news-slide for the carousel, .activities-grid for
   activities), not the wrap itself (which is always the wrap's own first child, so nth-child
   on the wrap would never vary). */
.news-slide > :nth-child(3n+2) .news-card-img,
.activities-grid > :nth-child(3n+2) .news-card-img { animation-duration: 12s; animation-direction: alternate-reverse; animation-delay: -6s; }
.news-slide > :nth-child(3n) .news-card-img,
.activities-grid > :nth-child(3n) .news-card-img { animation-duration: 14s; animation-delay: -9s; }

@keyframes kenburns {
  0% { transform: scale(1) translate(0, 0); }
  100% { transform: scale(1.22) translate(-3%, -3%); }
}

@media (prefers-reduced-motion: reduce) {
  .news-card-img { animation: none; }
}

/* --- News Gallery / Slideshow (ใน details modal) --- */
.news-gallery {
  width: 100% !important;
  max-width: 100% !important;
  border-radius: 10px;
  overflow: hidden !important;
  position: relative;
  background: rgba(0, 0, 0, 0.3);
  box-sizing: border-box;
}

.news-gallery.hidden {
  display: none !important;
}

/* รูปเดียวใน Popup Modal (แสดงผลแบบ Fit ภายในกรอบ ไม่ล้น และไม่โดนครอบตัดส่วนสำคัญ) */
.news-gallery-single {
  width: 100% !important;
  max-width: 100% !important;
  height: 260px !important;
  max-height: 260px !important;
  object-fit: contain !important;
  object-position: center !important;
  display: block !important;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.4);
}

/* Multi-image slideshow ใน Popup Modal */
.news-gallery-slides {
  position: relative;
  width: 100% !important;
  max-width: 100% !important;
  height: 260px !important;
  max-height: 260px !important;
  overflow: hidden !important;
  background: rgba(0, 0, 0, 0.4);
}

.news-gallery-slide {
  position: absolute;
  inset: 0;
  width: 100% !important;
  height: 100% !important;
  max-width: 100% !important;
  max-height: 100% !important;
  object-fit: contain !important;
  object-position: center !important;
  opacity: 0;
  /* Stacked absolutely on top of each other — without this, the hidden (opacity:0) slides still
     sit in front for hit-testing (later DOM siblings paint/receive clicks first by default), so
     every click/hover always hit the last image regardless of which one was visibly active. */
  pointer-events: none;
  transition: opacity 0.5s ease;
}

.news-gallery-slide.active {
  opacity: 1;
  pointer-events: auto;
}

.news-gallery-thumbs {
  display: flex;
  gap: 8px;
  padding: 10px 2px 0;
  overflow-x: auto;
  scrollbar-width: thin;
}

.news-gallery-thumb {
  flex: 0 0 auto;
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: 6px;
  cursor: pointer;
  opacity: 0.5;
  border: 2px solid transparent;
  transition: opacity 0.25s ease, border-color 0.25s ease;
}

.news-gallery-thumb:hover {
  opacity: 0.8;
}

.news-gallery-thumb.active {
  opacity: 1;
  border-color: var(--secondary-color, var(--primary-color));
}

/* --- Committee Org Chart Premium Styling & Animations --- */
.org-chart-grid {
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.org-chart-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 22px;
}

/* Outer glowing frame — animated gradient border ring around each member,
   like a slow-moving GIF light chasing the edge. The inner .committee-card
   sits on top with an opaque glass fill so only a thin ring peeks through. */
.committee-card-frame {
  position: relative;
  flex: 0 1 220px;
  padding: 3px;
  border-radius: calc(var(--radius-md) + 4px);
  background: linear-gradient(120deg, #00aaff, #00f2fe, #7928ca, #00aaff);
  background-size: 300% 300%;
  animation: cardFrameGlow 8s ease infinite;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.28);
  cursor: pointer;
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease;
}

.committee-card-frame:hover {
  transform: translateY(-8px) scale(1.03);
  box-shadow: 0 18px 42px rgba(0, 170, 255, 0.28), 0 0 32px rgba(0, 242, 254, 0.22);
}

@keyframes cardFrameGlow {
  0%, 100% { background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
}

/* Podium tiers by row position — gold / silver / bronze crowns so the
   hierarchy reads instantly, then the 4th+ tier falls back to the plain
   blue/cyan frame. */
.org-chart-row:first-child .committee-card-frame,
.org-chart-row:nth-child(2) .committee-card-frame,
.org-chart-row:nth-child(3) .committee-card-frame {
  background: linear-gradient(120deg, var(--tier-c1), var(--tier-c2), var(--tier-c3), var(--tier-c1));
  background-size: 300% 300%;
}

.org-chart-row:first-child { --tier-c1: #ffd700; --tier-c2: #ffb300; --tier-c3: #00aaff; }
.org-chart-row:nth-child(2) { --tier-c1: #e2e8f0; --tier-c2: #a8b3c4; --tier-c3: #00aaff; }
.org-chart-row:nth-child(3) { --tier-c1: #cd7f32; --tier-c2: #a1651f; --tier-c3: #00aaff; }

.org-chart-row:first-child .committee-card-frame::after,
.org-chart-row:nth-child(2) .committee-card-frame::after,
.org-chart-row:nth-child(3) .committee-card-frame::after {
  content: '👑';
  position: absolute;
  top: -16px;
  right: -4px;
  font-size: 1.5rem;
  animation: crownFloat 3s ease-in-out infinite;
  z-index: 2;
}

.org-chart-row:first-child .committee-card-frame::after {
  filter: drop-shadow(0 2px 6px rgba(255, 215, 0, 0.55));
}

.org-chart-row:nth-child(2) .committee-card-frame::after {
  /* gold emoji desaturated toward white/silver */
  filter: grayscale(1) brightness(1.55) drop-shadow(0 2px 6px rgba(200, 210, 225, 0.55));
}

.org-chart-row:nth-child(3) .committee-card-frame::after {
  /* gold emoji shifted toward copper/bronze */
  filter: sepia(1) saturate(2.2) hue-rotate(-25deg) brightness(0.85) drop-shadow(0 2px 6px rgba(205, 127, 50, 0.55));
}

@keyframes crownFloat {
  0%, 100% { transform: translateY(0) rotate(-6deg); }
  50% { transform: translateY(-4px) rotate(6deg); }
}

.committee-card {
  position: relative;
  background: var(--bg-glass);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-radius: calc(var(--radius-md) + 2px);
  padding: 26px 18px 22px;
  text-align: center;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
}

.committee-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--accent-gradient);
  opacity: 0.85;
}

.org-chart-row:first-child .committee-card::before,
.org-chart-row:nth-child(2) .committee-card::before,
.org-chart-row:nth-child(3) .committee-card::before {
  background: linear-gradient(120deg, var(--tier-c1), var(--tier-c2));
}

/* Avatar Ring & Rotating Neon Light Animation (Center Image) */
.committee-avatar-wrapper {
  position: relative;
  width: 96px;
  height: 96px;
  margin: 0 auto 16px auto;
  display: flex;
  align-items: center;
  justify-content: center;
}

.committee-avatar-ring {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: linear-gradient(45deg, #00aaff, #00f2fe, #7928ca, #00aaff);
  background-size: 300% 300%;
  animation: ringRotate 6s linear infinite;
  opacity: 0.85;
}

@keyframes ringRotate {
  0% { transform: rotate(0deg); background-position: 0% 50%; }
  50% { background-position: 100% 50%; }
  100% { transform: rotate(360deg); background-position: 0% 50%; }
}

.org-chart-row:first-child .committee-avatar-wrapper { width: 108px; height: 108px; }
.org-chart-row:nth-child(2) .committee-avatar-wrapper { width: 104px; height: 104px; }
.org-chart-row:nth-child(3) .committee-avatar-wrapper { width: 100px; height: 100px; }

.org-chart-row:first-child .committee-avatar-ring,
.org-chart-row:nth-child(2) .committee-avatar-ring,
.org-chart-row:nth-child(3) .committee-avatar-ring {
  background: linear-gradient(45deg, var(--tier-c1), var(--tier-c2), var(--tier-c3), var(--tier-c1));
  background-size: 300% 300%;
}

.org-chart-row:first-child .committee-avatar-img,
.org-chart-row:first-child .committee-avatar-fallback {
  width: 100px;
  height: 100px;
}

.org-chart-row:nth-child(2) .committee-avatar-img,
.org-chart-row:nth-child(2) .committee-avatar-fallback {
  width: 96px;
  height: 96px;
}

.org-chart-row:nth-child(3) .committee-avatar-img,
.org-chart-row:nth-child(3) .committee-avatar-fallback {
  width: 92px;
  height: 92px;
}

.committee-avatar-img {
  position: relative;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  object-fit: cover !important;
  object-position: center !important;
  border: 3px solid #0a0f1d;
  background: var(--bg-color);
  z-index: 1;
  display: block;
}

.committee-avatar-fallback {
  position: relative;
  width: 90px;
  height: 90px;
  border-radius: 50%;
  background: var(--secondary-gradient);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 1.8rem;
  color: #ffffff;
  border: 3px solid #0a0f1d;
  z-index: 1;
}

/* Name & Position Badge */
.committee-name {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text-main);
  margin-bottom: 8px;
}

.committee-badge {
  display: inline-block;
  padding: 4px 14px;
  border-radius: 20px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: rgba(0, 170, 255, 0.12);
  color: #00f2fe;
  border: 1px solid rgba(0, 170, 255, 0.3);
}

.org-chart-row:first-child .committee-badge {
  background: rgba(255, 215, 0, 0.14);
  color: #ffd700;
  border-color: rgba(255, 215, 0, 0.4);
}

.org-chart-row:nth-child(2) .committee-badge {
  background: rgba(226, 232, 240, 0.14);
  color: #e2e8f0;
  border-color: rgba(226, 232, 240, 0.4);
}

.org-chart-row:nth-child(3) .committee-badge {
  background: rgba(205, 127, 50, 0.16);
  color: #e0a262;
  border-color: rgba(205, 127, 50, 0.45);
}

.org-chart-row:first-child .committee-name { font-size: 1.15rem; }
.org-chart-row:nth-child(2) .committee-name { font-size: 1.1rem; }
.org-chart-row:nth-child(3) .committee-name { font-size: 1.08rem; }

.committee-division {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-top: 6px;
}

/* Social icons (member detail modal) — kept as inline SVG (crisp at any size,
   no external CDN/file dependency) but animated so they feel as alive as a
   GIF: a gentle idle pulse, then a springy bounce + brand-colored glow on
   hover/focus. */
.committee-social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--bg-glass);
  border: 1px solid var(--border-glass);
  color: var(--text-main);
  animation: iconIdlePulse 3s ease-in-out infinite;
  transition: color 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}

.committee-social-icon:nth-of-type(2) { animation-delay: 0.4s; }
.committee-social-icon:nth-of-type(3) { animation-delay: 0.8s; }
.committee-social-icon:nth-of-type(4) { animation-delay: 1.2s; }

@keyframes iconIdlePulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}

.committee-social-icon:hover,
.committee-social-icon:focus-visible {
  animation: iconBounce 0.6s ease;
  border-color: currentColor;
}

@keyframes iconBounce {
  0% { transform: scale(1) translateY(0); }
  30% { transform: scale(1.25) translateY(-6px); }
  50% { transform: scale(0.95) translateY(2px); }
  70% { transform: scale(1.1) translateY(-2px); }
  100% { transform: scale(1) translateY(0); }
}

.committee-social-icon.icon-ig:hover { color: #dd2a7b; box-shadow: 0 0 16px rgba(221, 42, 123, 0.5); }
.committee-social-icon.icon-fb:hover { color: #1877f2; box-shadow: 0 0 16px rgba(24, 119, 242, 0.5); }
.committee-social-icon.icon-yt:hover { color: #ff0000; box-shadow: 0 0 16px rgba(255, 0, 0, 0.5); }
.committee-social-icon.icon-line:hover { color: #06c755; box-shadow: 0 0 16px rgba(6, 199, 85, 0.5); }

.news-gallery-dot.active {
  background: var(--primary-color, #00aaff);
}

