/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

:root {
  /* Brand color - 레드 계열 */
  --color-primary: #FF0000;
  --color-primary-dark: #DC2626;
  --color-primary-light: #FCA5A5;
  --color-primary-lighter: #FEE2E2;

  /* Neutral colors */
  --color-bg: #F9FAFB;
  --color-card: #FFFFFF;
  --color-border: #E5E7EB;
  --color-text: #111827;
  --color-text-sub: #6B7280;
}

/* Safari bounce scroll 방지 */
body {
  overscroll-behavior: none;
  /* Pretendard is loaded via CDN in the layout <head>. The Variable version
     covers Korean + English with consistent metrics. We list system-Korean and
     -apple-system as fallbacks for the moment Pretendard hasn't loaded yet. */
  font-family: 'Pretendard Variable', 'Pretendard', -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
}

/* Hotwire Native shell — native iOS UITabBar replaces the web bottom-nav,
   and a custom UINavigationController nav bar (configured in SceneDelegate)
   replaces the web header. CSS forces them off as a safety net even if any
   JS accidentally un-hides them. */
body[data-hotwire-native="true"] #main-header,
body[data-hotwire-native="true"] #student-bottom-nav,
body[data-hotwire-native="true"] #company-bottom-nav,
body[data-hotwire-native="true"] #ed-header,
body[data-hotwire-native="true"] #ed-bottom-nav {
  display: none !important;
}

/* Every page on web puts top padding/margin on `<main>` purely to clear
   the fixed `<header>` (`pt-12`, `pt-16`, `mt-16`, `mt-24`, etc.). In the
   native shell that header is gone — Hotwire lays the WKWebView out under
   the iOS UINavigationBar so any extra top spacing becomes dead space.
   Collapse it for ALL `<main>` elements. Page-by-page allowlists turned
   into a constant maintenance tax (every new page repeats the bug). */
body[data-hotwire-native="true"] main {
  padding-top: 0 !important;
  margin-top: 0 !important;
}

/* List pages (events/projects/jobs/clubs/campaigns) pin a search + filter
   block at the top with `position: fixed; top: 48px` to clear the web header,
   then drop a hardcoded `h-44` (176px) spacer below to push the first card
   past the now-removed-from-flow block.

   In the native shell:
   1. The web header is gone, so we don't need the 48px offset.
   2. The block height is variable (category count, login state, admin role
      all change it), so a hardcoded spacer height will always be wrong on
      some configuration / device.

   Switch `fixed` → `sticky`. Sticky stays in normal flow, so it reserves
   exactly its own height — no spacer math needed at any screen size. The
   element still pins to `top: 0` once the user scrolls past it.

   Also tighten the block's vertical padding so the search input doesn't
   sit far below the iOS UINavigationBar. */
body[data-hotwire-native="true"] .md\:hidden.fixed.top-\[48px\] {
  position: sticky !important;
  top: 0 !important;
  /* Same horizontal padding on every list page (Events / Projects / Jobs /
     Clubs) so the search input + filter row align consistently across tabs.
     Matches the `px-4` baked into each page's bar markup. */
  padding: 0.5rem 1rem !important;
  /* Stretch full-bleed regardless of the parent wrapper's padding. Each list
     page has a different parent (Events/Projects/Jobs use `w-full px-2`,
     Clubs uses `container mx-auto px-0`), so a fixed negative margin can't
     cover all of them. The calc() trick centers a 100vw box on the viewport
     no matter how the parent is laid out — the bar's bg-white covers the
     full screen so cards behind it stay hidden as the list scrolls. */
  width: 100vw !important;
  margin-left: calc(50% - 50vw) !important;
}

/* Slimmer, capsule-shaped search input in the native shell — matches iOS
   native search field styling and frees up vertical space. */
body[data-hotwire-native="true"] .md\:hidden.fixed.top-\[48px\] input[type="text"] {
  padding-top: 0.5rem !important;
  padding-bottom: 0.5rem !important;
  border-radius: 9999px !important;
}

/* Spacer is redundant under sticky positioning. Use the adjacent-sibling
   selector so this catches every list page regardless of which fixed-height
   class it uses (h-44 on events/projects, h-26 on clubs, etc.) — keep a
   small gap so the first card doesn't sit flush against the filter pills. */
body[data-hotwire-native="true"] .md\:hidden.fixed.top-\[48px\] + .md\:hidden {
  height: 0.5rem !important; /* 8px breathing room */
}

/* Detail pages (events/projects/campaigns show) have a fixed bottom action
   bar pinned at `bottom: 0` with the Apply button. The native shell hides
   the UITabBar on these pages via `hidesBottomBarWhenPushed`, so the bar
   needs to:
   1. Stay glued to the actual bottom of the screen (`bottom: 0`).
   2. Push its inner buttons above the home indicator via `padding-bottom`
      so the gray background extends all the way down with no floating gap.
   Setting `bottom: env(safe-area-inset-bottom)` instead would leave dead
   space below the bar that visually "floats" while scrolling. */
body[data-hotwire-native="true"] .lg\:hidden.fixed.bottom-0 {
  bottom: 0 !important;
  padding-bottom: env(safe-area-inset-bottom) !important;
}

/* Top-of-page in-page back links (chevron + "Back to X") are redundant in
   the native shell — the iOS UINavigationBar already shows a system back
   chevron. Hide these so the UI doesn't have two stacked back affordances.
   Add the `app-back-link` class to any such link in the views and it
   disappears in the native app while staying visible on the web. */
body[data-hotwire-native="true"] .app-back-link {
  display: none !important;
}

/* Generic "hide this element only in the native shell" hook. Useful for
   elements that duplicate something the iOS nav bar already shows
   (e.g. a page-top H1 that matches the URL-based header label). */
body[data-hotwire-native="true"] .app-hidden {
  display: none !important;
}

/* Admin pages: hide every page-title <h1> inside #adminMain in the native
   shell. The iOS UINavigationBar already shows the per-section label
   (mapped per URL in SceneDelegate.swift's `urlLabelRules`), so the inline
   H1 (e.g. "학생 관리", "Events & Projects", "동아리 관리", ...) would
   stack a second redundant title under the system nav bar. h2/h3 sub-
   headings inside the page stay visible — they're real section markers,
   not page titles. */
body[data-hotwire-native="true"] #adminMain h1 {
  display: none !important;
}

/* Adds breathing room between the iOS UINavigationBar and the first
   page-content element. Margin (not padding) so the gap sits outside
   the element — important for tab pills / cards whose background would
   otherwise extend upward. Web mobile already has the fixed web header
   margin baked into the page layout, so this is native-only. */
body[data-hotwire-native="true"] .app-top-gap {
  margin-top: 1rem;
}



/* 모바일 더블탭 줌 + 핀치 줌 방지 */
* {
  touch-action: pan-x pan-y;
}

/* Primary/Brand color utilities - 로고, 강조 포인트용 */
.bg-primary { background-color: var(--color-primary) !important; }
.bg-primary-dark { background-color: var(--color-primary-dark) !important; }
.bg-primary-light { background-color: var(--color-primary-light) !important; }
.bg-primary-lighter { background-color: var(--color-primary-lighter) !important; }
.text-primary { color: var(--color-primary) !important; }
.text-primary-dark { color: var(--color-primary-dark) !important; }
.text-primary-light { color: var(--color-primary-light) !important; }
.border-primary { border-color: var(--color-primary) !important; }
.border-primary-light { border-color: var(--color-primary-light) !important; }
.stroke-primary { stroke: var(--color-primary) !important; }

/* Hover states */
.hover\:bg-primary-dark:hover { background-color: var(--color-primary-dark) !important; }
.hover\:bg-primary-light:hover { background-color: var(--color-primary-light) !important; }
.hover\:text-primary:hover { color: var(--color-primary) !important; }
.hover\:text-primary-dark:hover { color: var(--color-primary-dark) !important; }
.hover\:border-primary:hover { border-color: var(--color-primary) !important; }
.hover\:border-primary-light:hover { border-color: var(--color-primary-light) !important; }

/* Focus ring */
.focus\:ring-primary:focus { --tw-ring-color: var(--color-primary-light) !important; }
.focus\:border-primary:focus { border-color: var(--color-primary) !important; }

/* Gradient utilities - 빨간색 계열 그라데이션 */
.bg-gradient-primary {
  background: linear-gradient(135deg, #FF0000 0%, #DC2626 100%) !important;
}
.bg-gradient-primary-light {
  background: linear-gradient(135deg, #FEE2E2 0%, #FECACA 100%) !important;
}
.bg-gradient-primary-soft {
  background: linear-gradient(135deg, #FFF5F5 0%, #FEE2E2 100%) !important;
}
.bg-gradient-primary-to-orange {
  background: linear-gradient(135deg, #FF0000 0%, #F97316 100%) !important;
}
.bg-gradient-primary-radial {
  background: radial-gradient(circle at top right, #FCA5A5 0%, #FEE2E2 50%, #FFFFFF 100%) !important;
}

/* Rich text preview (description_only fields) */
.field-rich-preview a { color: #2563eb; text-decoration: underline; }
.field-rich-preview ul { list-style-type: disc; padding-left: 1.5em; margin: 0.25em 0; }
.field-rich-preview ol { list-style-type: decimal; padding-left: 1.5em; margin: 0.25em 0; }

/* Campaign description rich text (replaces @tailwindcss/typography prose) */
.campaign-description ul { list-style-type: disc; padding-left: 1.5em; margin: 0.5em 0; }
.campaign-description ol { list-style-type: decimal; padding-left: 1.5em; margin: 0.5em 0; }
.campaign-description li { margin: 0.25em 0; }
.campaign-description li ul { list-style-type: circle; margin: 0.25em 0; }
.campaign-description li ol { margin: 0.25em 0; }
.campaign-description a { color: #2563eb; text-decoration: underline; }
.campaign-description strong, .campaign-description b { font-weight: 700; }
.campaign-description em, .campaign-description i { font-style: italic; }
.campaign-description u { text-decoration: underline; }
.campaign-description p { margin: 0.5em 0; }
.campaign-description h1, .campaign-description h2, .campaign-description h3 { font-weight: 700; margin: 0.75em 0 0.25em; }
.campaign-description h1 { font-size: 1.5em; }
.campaign-description h2 { font-size: 1.25em; }
.campaign-description h3 { font-size: 1.1em; }

/* Safe area for mobile (iPhone notch/dynamic island) */
.safe-area-bottom {
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.safe-area-top {
  padding-top: env(safe-area-inset-top, 0);
}
