/* =========================================================
   Blue Glass Intelligence — design tokens, reset, primitives
   Load order: base.css → layout.css → sections.css
   ========================================================= */
:root {
  /* surface — the two base colours also ship as raw channels, because a dozen
     rules build their own translucency out of them (headers, glass panels, the
     scroll scrims). Channels let those follow the theme without each rule
     needing a dark twin. */
  --page-bg: #f7faff;
  --page-bg-rgb: 247, 250, 255;
  --page-bg-secondary: #f1f6ff;
  --surface: #ffffff;
  --surface-rgb: 255, 255, 255;
  --surface-soft: rgba(var(--surface-rgb), 0.78);
  --surface-blue: #eef5ff;

  /* text */
  --text-primary: #0f1b2d;
  --text-secondary: #4f6078;
  /* 4.90:1 on the tinted chip background, 5.33:1 on white. The previous
     #64748c came in at 4.37:1 once measured against the actual chip rather
     than the page, which misses AA for the 12px labels that use it. */
  --text-tertiary: #5e6c82;
  --text-inverse: #ffffff;
  /* The hero sits over moving glass, so its text is darkened past the ordinary
     secondary greys to hold 4.5:1 while a panel slides underneath. */
  --text-scrim-strong: #1e2c42;
  --text-scrim: #2a374d;

  /* brand */
  --primary-700: #1d4ed8;
  --primary-600: #2563eb;
  --primary-500: #3182f6;
  --primary-400: #4b96ff;
  --primary-300: #78b4ff;
  --primary-200: #b9d8ff;
  --primary-100: #dcecff;
  --primary-50: #eff6ff;

  --cyan-500: #06b6d4;
  --cyan-400: #22d3ee;
  --cyan-300: #67e8f9;

  --border-default: rgba(37, 99, 235, 0.11);
  --border-strong: rgba(37, 99, 235, 0.2);

  --success: #18a874;
  --warning: #e89b21;
  --danger: #e65c6a;
  --danger-text: #8f2f3b;

  /* Split out from --primary-700 because this one is a *background* carrying
     white text. In dark mode --primary-700 becomes a light blue for text, and
     white on light blue would be unreadable. */
  --skip-bg: var(--primary-700);
  --badge-bg: rgba(239, 246, 255, 0.8);

  /* Three gradients, split by what sits on top of them.

     --grad-cta carries white 14px labels, so every point along it has to clear
     4.5:1. The old blue→cyan ramp measured 2.51:1 where the label crosses the
     cyan end — Lighthouse never caught it because it does not evaluate
     background-image. Deepening the far stop to teal keeps the blue→cyan read
     and puts the whole ramp at 5.17:1 or better.

     --grad-mark keeps the original vivid ramp for the 22px wordmark tile and
     the cursor dot, which carry no text.

     --grad-head is clipped to the hero heading, so it is text itself and flips
     in dark mode. */
  --grad-cta: linear-gradient(135deg, #1d4ed8 0%, #2563eb 55%, #0e7490 100%);
  --grad-mark: linear-gradient(135deg, #1d4ed8 0%, #3182f6 55%, #22d3ee 100%);
  --grad-head: linear-gradient(120deg, #1d4ed8 0%, #2563eb 55%, #3182f6 100%);

  /* spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 48px;
  --space-10: 64px;
  --space-11: 80px;
  --space-12: 96px;
  --space-13: 120px;

  /* radius */
  --radius-xs: 8px;
  --radius-sm: 12px;
  --radius-md: 16px;
  --radius-lg: 22px;
  --radius-xl: 28px;
  --radius-2xl: 36px;
  --radius-pill: 999px;

  /* shadow */
  --shadow-xs: 0 2px 8px rgba(29, 78, 216, 0.04);
  --shadow-sm: 0 8px 24px rgba(29, 78, 216, 0.07);
  --shadow-md: 0 18px 48px rgba(29, 78, 216, 0.1);
  --shadow-lg: 0 30px 80px rgba(29, 78, 216, 0.14);
  --shadow-glow: 0 18px 50px rgba(49, 130, 246, 0.24);

  /* layout */
  --header-h: 72px;
  --section-y: clamp(64px, 9vw, 120px);
  --gutter: clamp(20px, 4vw, 32px);

  --font-sans: "Pretendard Variable", Pretendard, Inter, "Noto Sans KR",
    -apple-system, BlinkMacSystemFont, "Segoe UI", "Apple SD Gothic Neo",
    "Malgun Gothic", sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Code", Consolas, monospace;

  --ease: cubic-bezier(0.22, 0.7, 0.24, 1);
}

/* =========================================================
   Dark mode

   Everything below only re-points the tokens above, so no component
   carries a dark branch of its own. Two deliberate exceptions:

   - --text-inverse stays white. It labels the blue gradient buttons and
     the chat bubble, and that gradient does not flip.
   - The blue ramp splits by role. 700/600/300 are read as *text* on this
     page, so they get lighter; 100/50 are read as *fills*, so they get
     darker. Flipping the whole ramp one way would break the other half.
   ========================================================= */
@media (prefers-color-scheme: dark) {
  :root {
    --page-bg: #0b1220;
    --page-bg-rgb: 11, 18, 32;
    --page-bg-secondary: #0e1526;
    --surface: #151d2e;
    --surface-rgb: 21, 29, 46;
    --surface-blue: #14203a;

    --text-primary: #e9eefb;
    --text-secondary: #aab9d6;
    --text-tertiary: #93a3bf;
    --text-scrim-strong: #e3eaf9;
    --text-scrim: #cbd6ec;

    /* text-weight blues */
    --primary-700: #a8c6ff;
    --primary-600: #8db4ff;
    --primary-300: #6ea4ff;
    /* fill-weight blues */
    --primary-100: #1d2b48;
    --primary-50: #16223c;

    --border-default: rgba(125, 170, 255, 0.14);
    --border-strong: rgba(125, 170, 255, 0.3);

    --success: #34d399;
    --danger-text: #ff9aa5;

    --skip-bg: #1d4ed8;
    --badge-bg: rgba(37, 99, 235, 0.18);

    /* The heading gradient is the text, so it inverts. Its darkest stop
       measured 2.79:1 against the dark page — under the 3:1 large-text floor. */
    --grad-head: linear-gradient(120deg, #7fb0ff 0%, #9cc3ff 55%, #7fe8f8 100%);

    /* Blue-tinted shadows vanish against a dark page; these carry depth. */
    --shadow-xs: 0 2px 8px rgba(0, 0, 0, 0.3);
    --shadow-sm: 0 8px 24px rgba(0, 0, 0, 0.36);
    --shadow-md: 0 18px 48px rgba(0, 0, 0, 0.44);
    --shadow-lg: 0 30px 80px rgba(0, 0, 0, 0.5);
  }
}

/* =========================================================
   Reset + base elements
   ========================================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 24px);
  -webkit-text-size-adjust: 100%;
  /* The intro gate and the mobile nav both lock the body, which removes the
     scrollbar and widens the page by its width — every element reflows.
     Lighthouse measured CLS 0.183 on desktop from exactly that, and 0 on
     mobile, where there is no scrollbar to lose. Reserving the gutter up
     front means locking scroll no longer moves anything. */
  scrollbar-gutter: stable;
}

body {
  min-height: 100%;
  overflow-x: hidden;
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.65;
  /* 한글은 단어 중간에서 줄바꿈되지 않도록 어절 단위로 끊는다 */
  word-break: keep-all;
  overflow-wrap: anywhere;
  background-color: var(--page-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body.is-locked {
  overflow: hidden;
}

img,
svg {
  display: block;
  max-width: 100%;
}

ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 3px solid rgba(49, 130, 246, 0.36);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

/* =========================================================
   Accessibility helpers
   ========================================================= */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100px;
  left: 16px;
  z-index: 100;
  padding: 12px 20px;
  border-radius: var(--radius-sm);
  color: var(--text-inverse);
  font-size: 14px;
  font-weight: 650;
  background: var(--skip-bg);
  transition: top 180ms var(--ease);
}

.skip-link:focus-visible {
  top: 16px;
}

/* decorative page wash — kept subtle and behind everything */
.page-wash {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(circle at 78% 6%, rgba(49, 130, 246, 0.13), transparent 34%),
    radial-gradient(circle at 12% 40%, rgba(34, 211, 238, 0.08), transparent 28%),
    radial-gradient(circle at 88% 78%, rgba(79, 70, 229, 0.06), transparent 30%),
    var(--page-bg);
}

/* =========================================================
   Layout primitives
   ========================================================= */
.site-container {
  width: min(100% - (var(--gutter) * 2), 1200px);
  margin-inline: auto;
}

/* 인접 섹션의 상하 패딩이 겹쳐 커지지 않도록 위쪽에만 준다 */
.section {
  padding-block: var(--section-y) 0;
}

.section--tight {
  padding-block: clamp(48px, 6vw, 72px) 0;
}

main > .section:last-child {
  padding-bottom: var(--section-y);
}

.section-header {
  max-width: 680px;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.section-header h2 {
  font-size: clamp(31px, 4.2vw, 40px);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.section-header h2 em {
  font-style: normal;
  color: var(--primary-600);
}

.section-header p {
  max-width: 62ch;
  margin-top: var(--space-4);
  color: var(--text-secondary);
  font-size: 17px;
  line-height: 1.7;
}

.eyebrow {
  display: block;
  margin-bottom: var(--space-4);
  color: var(--primary-600);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.eyebrow-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 34px;
  padding: 0 14px;
  border: 1px solid rgba(37, 99, 235, 0.13);
  border-radius: var(--radius-pill);
  color: var(--primary-700);
  font-size: 13px;
  font-weight: 650;
  background: var(--badge-bg);
}

.eyebrow-badge .status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px rgba(24, 168, 116, 0.16);
}

/* =========================================================
   Buttons
   ========================================================= */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 50px;
  padding: 0 23px;
  border: 0;
  border-radius: 15px;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: -0.005em;
  white-space: nowrap;
  transition:
    transform 180ms var(--ease),
    box-shadow 180ms var(--ease),
    border-color 180ms var(--ease),
    color 180ms var(--ease),
    filter 180ms var(--ease);
}

.button svg {
  flex: none;
}

.button-primary {
  color: var(--text-inverse);
  background: var(--grad-cta);
  box-shadow: 0 12px 30px rgba(37, 99, 235, 0.24);
}

.button-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 38px rgba(37, 99, 235, 0.3);
  filter: saturate(1.05);
}

.button-primary:active {
  transform: translateY(0);
}

.button-secondary {
  border: 1px solid rgba(37, 99, 235, 0.16);
  color: var(--primary-700);
  background: rgba(var(--surface-rgb), 0.82);
  box-shadow: 0 8px 22px rgba(29, 78, 216, 0.06);
}

.button-secondary:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: 0 12px 28px rgba(29, 78, 216, 0.09);
}

.button-secondary:active {
  transform: translateY(0);
}

.button--sm {
  min-height: 42px;
  padding: 0 16px;
  border-radius: 12px;
  font-size: 14px;
}

/* =========================================================
   Scroll reveal — only active once JS has run
   ========================================================= */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 520ms var(--ease),
    transform 520ms var(--ease);
}

.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

.js .reveal[data-delay="1"] {
  transition-delay: 70ms;
}

.js .reveal[data-delay="2"] {
  transition-delay: 140ms;
}

.js .reveal[data-delay="3"] {
  transition-delay: 210ms;
}

/* =========================================================
   Responsive
   ========================================================= */
@media (max-width: 1023px) {
  .hide-md {
    display: none;
  }
}

@media (max-width: 359px) {
  :root {
    --gutter: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }
}

@media print {
  .site-header,
  .page-wash,
  .hero-visual,
  .skip-link {
    display: none;
  }

  body {
    background: #fff;
  }
}
